[support] Memory corruption in ha.c?

Tero Kauppinen (JO/LMF) tero.kauppinen at ericsson.com
Mon Aug 11 18:32:28 JST 2008


Hello

1) I suspect that there can be a possibility for a memory corruption in 
ha.c. Referring to the file at:

http://www.linux-ipv6.org/gitweb/gitweb.cgi?p=gitroot/mipv6-daemon.git;a=blob;h=f6d5cda76c7f72b48e490b874f3f6e53974df5ea;hb=master;f=src/ha.c

Function ha_recv_bu_worker on line:

  874         *(arg->statusp) = status;

When a ha_recv_bu_worker thread is created in ha_recv_bu_main, it stores 
a pointer to a local status variable (line 895: int status = 0; and line 
934: arg->statusp = &status;) which is then used at that above 874 line 
to return the status value. However, if no join is requested (i.e. 
!(arg->flags & HA_BU_F_THREAD_JOIN), ha_recv_bu_main exists and thus a 
pointer to the local variable points somewhere in the memory which might 
no longer be usable.

2) in ha_recv_bu_worker free(arg) is called already at line 863, which 
means arg is used when the memory it points to is already freed (line 874).

Both 1) and 2) could be fixed in the following way:

out:
         pthread_mutex_lock(&bu_worker_mutex);
         if (!list_empty(&bu_worker_list)) {
                 struct list_head *l = bu_worker_list.next;
                 list_del(l);
                 free(arg);
                 arg = list_entry(l, struct ha_recv_bu_args, list);
                 pthread_mutex_unlock(&bu_worker_mutex);
                 goto restart;
         }
         if (--bu_worker_count == 0)
                 pthread_cond_signal(&cond);

         /* statusp points to a variable in the ha_recv_bu_main 		
          * function's stack and MUST not be used unless the
          * function is waiting for the thread in pthread_join().
          */
         if (arg->flags & HA_BU_F_THREAD_JOIN)
                 *(arg->statusp) = status;
         free(arg);
         pthread_mutex_unlock(&bu_worker_mutex);
         pthread_exit(NULL);

Any thoughts?

/Tero


More information about the Support mailing list