]> Zhao Yanbai Git Server - minix.git/commitdiff
procfs: fix rare panic in add_inode
authorDavid van Moolenbroek <david@minix3.org>
Tue, 17 Apr 2012 15:51:26 +0000 (17:51 +0200)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 19 Apr 2012 09:26:11 +0000 (11:26 +0200)
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.

servers/procfs/tree.c

index cb265cb478f8082c9da956480d263891734c7d7d..35c0a6f5aa3e074ab6891eb58554e4f96eb1f7e8 100644 (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);