NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/41225: sys_mqueue.c mq->mq_notify_proc can disappear



>Number:         41225
>Category:       kern
>Synopsis:       sys_mqueue.c mq->mq_notify_proc can disappear
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 15 22:10:01 +0000 2009
>Originator:     Andrew Doran
>Release:        5.0
>Organization:
The NetBSD Project
>Environment:
n/a
>Description:
Message queues are tied to file descriptors and so can live across
fork().

mq_notify() does: mq->mq_notify_proc = l->l_proc;

It looks like this process can exit while the mqueue still persists.

We can later try to send a signal to this process.
>How-To-Repeat:
Code inspection.

>Fix:
This problem occurs quite a few times in the kernel, esp. in device
drivers doing async I/O. :-(

Quick and dirty fix:

Change mq_notify() to store a pid_t and use p_find() when sending
signals. mqueue can send signals to unrelated processes after
the proc exits.

More reliable but ugly and slow:

Register an exithook for every mqueue that has mq_notify_proc set.
This is mostly ugly because at the moment it requires taking exec_lock
which is pretty heavyweight.

Maybe a better solution:

In addition to a pid, store a generation number per struct proc.
Every time a pid is allocated, increment the generation number.
Add a p_find_gen() or similar that looks for a pid and also
compares the generation numbers.
This number could be a 64-bit system global (under proc_lock) or
we could have one for each pid table slot. I don't personally see
a big disadvantage to having a global. ??



Home | Main Index | Thread Index | Old Index