Messages in this thread Patch in this message | | | From | Patrick Schaaf <> | Subject | /proc and chroot, again | Date | Fri, 25 Jun 1999 21:11:29 +0200 (MEST) |
| |
Hi,
inspired by the recent discussion on chroot and /proc, I made the appended patch to 2.3.8.
The first chunk of the patch adds a call to proc_permission to proc_base_inode_ops, resulting in ENOENT when trying to lookup /proc/<pid> processes that have their fs->root outside the current->fs->root tree. The remainder of the patch hides those processes from readdir(/proc).
A stat() or lstat() on "outside" /proc/<pid> stuff still works, because fs/stat.c does not use 'permission' at all. Personally, I don't consider that a security problem. I even see the readdir hiding as cosmetics - it is cmdline and environ for "outside" processes I'm concerned about.
regards Patrick
diff -urN linux-2.3.8/fs/proc/base.c patch-linux/fs/proc/base.c --- linux-2.3.8/fs/proc/base.c Sat Jun 19 20:45:28 1999 +++ patch-linux/fs/proc/base.c Fri Jun 25 12:18:40 1999 @@ -50,7 +50,7 @@ NULL, /* writepage */ NULL, /* flushpage */ NULL, /* truncate */ - NULL, /* permission */ + proc_permission, /* permission */ NULL, /* smap */ NULL /* revalidate */ }; diff -urN linux-2.3.8/fs/proc/inode.c patch-linux/fs/proc/inode.c --- linux-2.3.8/fs/proc/inode.c Tue Jun 8 19:47:58 1999 +++ patch-linux/fs/proc/inode.c Fri Jun 25 17:36:08 1999 @@ -175,6 +175,23 @@ * * Jeremy Fitzhardinge <jeremy@zip.com.au> */ + +int proc_is_under(struct dentry *base, struct dentry *de) +{ + if (base && de) { + /* XXX locking? */ + for(;;) { + struct dentry *parent; + if (de == base) return 1; + de = de->d_covers; + parent = de->d_parent; + if (de == parent) break; + de = parent; + } + } + return 0; +} + int proc_permission(struct inode *inode, int mask) { struct task_struct *p; @@ -207,33 +224,7 @@ de = p->fs->root; read_unlock(&tasklist_lock); /* FIXME! */ - if (p == NULL) - return -EACCES; /* ENOENT? */ - - if (de == NULL) - { - /* kswapd and bdflush don't have proper root or cwd... */ - return -EACCES; - } - - /* XXX locking? */ - for(;;) - { - struct dentry *parent; - - if (de == base) - return 0; /* already allowed */ - - de = de->d_covers; - parent = de->d_parent; - - if (de == parent) - break; - - de = parent; - } - - return -EACCES; /* incompatible roots */ + return proc_is_under(base, de) ? 0 : -ENOENT; } struct inode * proc_get_inode(struct super_block * sb, int ino, diff -urN linux-2.3.8/fs/proc/root.c patch-linux/fs/proc/root.c --- linux-2.3.8/fs/proc/root.c Sat Jun 19 20:45:29 1999 +++ patch-linux/fs/proc/root.c Fri Jun 25 17:36:08 1999 @@ -945,6 +945,8 @@ #define PROC_NUMBUF 10 #define PROC_MAXPIDS 20 +extern int proc_is_under(struct dentry *base, struct dentry *de); + /* * Get a few pid's to return for filldir - we need to hold the * tasklist lock while doing this, and we must release it before @@ -954,12 +956,16 @@ { struct task_struct *p; int nr_pids = 0; + struct dentry *base = current->fs ? current->fs->root : NULL; index -= FIRST_PROCESS_ENTRY; read_lock(&tasklist_lock); for_each_task(p) { int pid = p->pid; + struct dentry *de = p->fs ? p->fs->root : NULL; if (!pid) + continue; + if (!proc_is_under(base, de)) continue; if (--index >= 0) continue; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |