summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2020-08-02 01:32:43 +0200
committerGravatar Nikias Bassen2020-08-02 01:32:43 +0200
commit540e0c1fb988b926b625618c8bf31c8311f37e19 (patch)
treeca69e26edf014751a92e1eb0302951a6382c93a9
parentefa547103b619e62c7e41a305e5429055dcea370 (diff)
downloadusbmuxd-540e0c1fb988b926b625618c8bf31c8311f37e19.tar.gz
usbmuxd-540e0c1fb988b926b625618c8bf31c8311f37e19.tar.bz2
client: Prevent UaF in client_close() by checking if client is valid
-rw-r--r--src/client.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/client.c b/src/client.c
index 52e569d..7395046 100644
--- a/src/client.c
+++ b/src/client.c
@@ -251,6 +251,20 @@ int client_accept(int listenfd)
void client_close(struct mux_client *client)
{
+ int found = 0;
+ pthread_mutex_lock(&client_list_mutex);
+ FOREACH(struct mux_client *lc, &client_list) {
+ if (client == lc) {
+ found = 1;
+ break;
+ }
+ } ENDFOREACH
+ if (!found) {
+ // in case we get called again but client was already freed
+ usbmuxd_log(LL_DEBUG, "%s: ignoring for non-existing client %p", __func__, client);
+ pthread_mutex_unlock(&client_list_mutex);
+ return;
+ }
#ifdef SO_PEERCRED
if (log_level >= LL_INFO) {
struct ucred cr;
@@ -278,7 +292,6 @@ void client_close(struct mux_client *client)
free(client->ib_buf);
plist_free(client->info);
- pthread_mutex_lock(&client_list_mutex);
collection_remove(&client_list, client);
pthread_mutex_unlock(&client_list_mutex);
free(client);