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.
This commit is contained in:
David van Moolenbroek 2012-04-17 17:51:26 +02:00
parent 861bb4e571
commit 093c949274

View file

@ -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);