[support] Memory corruption in ha.c?
Romain KUNTZ
kuntz at lsiit.u-strasbg.fr
Sat Aug 23 02:18:24 JST 2008
Hi Tero,
Sorry for this delayed reply! Comments inline.
On 2008/08/11, at 2:32, Tero Kauppinen (JO/LMF) wrote:
> 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.
Good catch. Actually the HA_BU_F_THREAD_JOIN flag is not even ever
set, so what you describe will always happen.
> 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).
Yes, another great catch!
> 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);
What you propose is IMHO the right way to do. I'll send a mail ASAP to
the UMIP maintainers (and CC you) in order to try to push your patch
to the main UMIP repository.
Thanks,
--
Romain KUNTZ
kuntz at lsiit.u-strasbg.fr
LSIIT - Networks and Protocols Team
http://clarinet.u-strasbg.fr/~kuntz/
More information about the Support
mailing list