From: David van Moolenbroek Date: Tue, 17 Apr 2012 15:51:26 +0000 (+0200) Subject: procfs: fix rare panic in add_inode X-Git-Tag: v3.2.1~577 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/addsub.png?a=commitdiff_plain;h=093c949274ac8733dc936d5734c6cf4cbcbbf9fa;p=minix.git procfs: fix rare panic in add_inode Previously, procfs would consider all processes that have a non-free kernel slot *or* an in-use PM slot. However, since AVFS, a non-free kernel slot does not imply an in-use PM slot. As a result, procfs may use PM slots that have a zero PID value. If two such entries are present in the retrieved PM table, procfs would try to add two inodes with the same name "0", triggering an assertion in vtreefs. This patch makes procfs consider only the PM slot for (non-task) processes. --- diff --git a/servers/procfs/tree.c b/servers/procfs/tree.c index cb265cb47..35c0a6f5a 100644 --- a/servers/procfs/tree.c +++ b/servers/procfs/tree.c @@ -16,9 +16,18 @@ static int slot_in_use(int slot) /* Return whether the given slot is in use by a process. */ - return (proc[slot].p_rts_flags != RTS_SLOT_FREE || - (slot >= NR_TASKS && - (mproc[slot - NR_TASKS].mp_flags & IN_USE))); + /* For kernel tasks, check only the kernel slot. Tasks do not have a + * PM/VFS process slot. + */ + if (slot < NR_TASKS) + return (proc[slot].p_rts_flags != RTS_SLOT_FREE); + + /* For regular processes, check only the PM slot. Do not check the + * kernel slot, because that would skip zombie processes. The PID check + * should be redundant, but if it fails, procfs could crash. + */ + return ((mproc[slot - NR_TASKS].mp_flags & IN_USE) && + mproc[slot - NR_TASKS].mp_pid != 0); } /*===========================================================================* @@ -396,7 +405,7 @@ static void pid_read(struct inode *node) index = get_inode_index(node); /* Call the handler procedure for the file. */ -((void (*) (int)) pid_files[index].data)(slot); + ((void (*) (int)) pid_files[index].data)(slot); } /*===========================================================================* @@ -498,7 +507,7 @@ int read_hook(struct inode *node, off_t off, char **ptr, if (get_inode_index(node) != NO_INDEX) { pid_read(node); } else { - ((void (*) (void)) cbdata)(); + ((void (*) (void)) cbdata)(); } *len = buf_get(ptr);