From 5121a9aa0299a2c23b3c50bf110ab4a05677c740 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 5 Mar 2012 13:32:47 +0100 Subject: [PATCH] Add client references We have a use-after-free in the fio_handle_clients() loop. If we receive a QUIT command, we remove the client in fio_handle_client(). But fio_handle_clients() doesn't have a way to detect this, so it checks client->error after it has potentially been freed. Add a simple reference to get rid of this problem. Signed-off-by: Jens Axboe --- client.c | 17 ++++++++++++++++- client.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/client.c b/client.c index a65cbcba..b0ccad04 100644 --- a/client.c +++ b/client.c @@ -93,8 +93,10 @@ static struct fio_client *find_client_by_fd(int fd) flist_for_each(entry, &client_hash[bucket]) { client = flist_entry(entry, struct fio_client, hash_list); - if (client->fd == fd) + if (client->fd == fd) { + client->refs++; return client; + } } return NULL; @@ -102,6 +104,11 @@ static struct fio_client *find_client_by_fd(int fd) static void remove_client(struct fio_client *client) { + assert(client->refs); + + if (--client->refs) + return; + dprint(FD_NET, "client: removed <%s>\n", client->hostname); flist_del(&client->list); @@ -123,6 +130,11 @@ static void remove_client(struct fio_client *client) sum_stat_clients--; } +static void put_client(struct fio_client *client) +{ + remove_client(client); +} + static void __fio_client_add_cmd_option(struct fio_client *client, const char *opt) { @@ -187,6 +199,7 @@ struct fio_client *fio_client_add_explicit(struct client_ops *ops, client->fd = -1; client->ops = ops; + client->refs = 1; __fio_client_add_cmd_option(client, "fio"); @@ -235,6 +248,7 @@ int fio_client_add(struct client_ops *ops, const char *hostname, void **cookie) client->fd = -1; client->ops = ops; + client->refs = 1; __fio_client_add_cmd_option(client, "fio"); @@ -1116,6 +1130,7 @@ int fio_handle_clients(struct client_ops *ops) retval = 1; } else if (client->error) retval = 1; + put_client(client); } } diff --git a/client.h b/client.h index d0f9b281..213987ca 100644 --- a/client.h +++ b/client.h @@ -23,6 +23,7 @@ struct fio_client { char *hostname; int port; int fd; + unsigned int refs; char *name; -- 2.25.1