]> sourceware.org Git - lvm2.git/commitdiff
clvmd: hardening leak on exit
authorZdenek Kabelac <zkabelac@redhat.com>
Tue, 25 Mar 2014 09:50:36 +0000 (10:50 +0100)
committerZdenek Kabelac <zkabelac@redhat.com>
Tue, 25 Mar 2014 10:22:57 +0000 (11:22 +0100)
Operate with lvm_thread_exit while holding lvm_thread_mutex.
Don't leave unfinished work in the lvm thread queue
and always finish all queued tasks before exit,
so no cmd struct is left in the list.

(in-release fix)

daemons/clvmd/clvmd.c

index 46484501151f3672825c6653e5f9322a9c518503..bc98ccb4cfbe3981f032b214b7602ead3c2ba016 100644 (file)
@@ -2020,11 +2020,8 @@ static void *lvm_thread_fn(void *arg)
        /* Now wait for some actual work */
        pthread_mutex_lock(&lvm_thread_mutex);
 
-       while (!lvm_thread_exit)
-               if (dm_list_empty(&lvm_cmd_head)) {
-                       DEBUGLOG("LVM thread waiting for work\n");
-                       pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
-               } else {
+       for (;;) {
+               while (!dm_list_empty(&lvm_cmd_head)) {
                        cmd = dm_list_item(dm_list_first(&lvm_cmd_head),
                                           struct lvm_thread_cmd);
                        dm_list_del(&cmd->list);
@@ -2037,6 +2034,13 @@ static void *lvm_thread_fn(void *arg)
                        pthread_mutex_lock(&lvm_thread_mutex);
                }
 
+               if  (lvm_thread_exit)
+                       break;
+
+               DEBUGLOG("LVM thread waiting for work\n");
+               pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
+       }
+
        pthread_mutex_unlock(&lvm_thread_mutex);
        DEBUGLOG("LVM thread exits\n");
 
@@ -2051,9 +2055,6 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
 {
        struct lvm_thread_cmd *cmd;
 
-       if (lvm_thread_exit)
-               return -1; /* We are about to exit */
-
        if (!(cmd = dm_malloc(sizeof(*cmd))))
                return ENOMEM;
 
@@ -2081,6 +2082,12 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
        DEBUGLOG("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
                 cmd, client, msg, msglen, csid, cmd->xid);
        pthread_mutex_lock(&lvm_thread_mutex);
+       if (lvm_thread_exit) {
+               pthread_mutex_unlock(&lvm_thread_mutex);
+               dm_free(cmd->msg);
+               dm_free(cmd);
+               return -1; /* We are about to exit */
+       }
        dm_list_add(&lvm_cmd_head, &cmd->list);
        pthread_cond_signal(&lvm_thread_cond);
        pthread_mutex_unlock(&lvm_thread_mutex);
This page took 0.035753 seconds and 5 git commands to generate.