[PATCH] A better fix for nasty /proc vulnerability (CVE-2006-3626) This patch stops anyone from chmod'ing files in /proc, so that nobody can make it executable. This also reverts the previous fix that only removed the S_ISUID/ISGID from i_mode. Signed-off-by: Eugene Teo Signed-off-by: Marcel Holtmann --- commit c8dca639f7172828b7a677e92cf81c7df3a9405c tree 2a5e489d53dabcb849cc3ddab30d125cd402b30e parent d6c93e1ddde769010f9c81bbfab41a9844c0e9ba author Marcel Holtmann Sat, 15 Jul 2006 16:30:40 +0200 committer Marcel Holtmann Sat, 15 Jul 2006 16:30:40 +0200 fs/proc/base.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 474eae3..45da4f1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -551,6 +551,15 @@ static int proc_fd_access_allowed(struct return allowed; } +static int proc_setattr(struct dentry *dentry, struct iattr *attr) +{ + return -EPERM; +} + +static struct inode_operations proc_def_inode_operations = { + .setattr = proc_setattr, +}; + extern struct seq_operations mounts_op; struct proc_mounts { struct seq_file m; @@ -1111,7 +1120,8 @@ out: static struct inode_operations proc_pid_link_inode_operations = { .readlink = proc_pid_readlink, - .follow_link = proc_pid_follow_link + .follow_link = proc_pid_follow_link, + .setattr = proc_setattr, }; static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) @@ -1285,6 +1295,7 @@ static struct inode *proc_pid_make_inode ei = PROC_I(inode); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_ino = fake_ino(task->pid, ino); + inode->i_op = &proc_def_inode_operations; /* * grab the reference to task. @@ -1339,7 +1350,6 @@ static int pid_revalidate(struct dentry inode->i_uid = 0; inode->i_gid = 0; } - inode->i_mode &= ~(S_ISUID | S_ISGID); security_task_to_inode(task, inode); put_task_struct(task); return 1; @@ -1390,7 +1400,6 @@ static int tid_fd_revalidate(struct dent inode->i_uid = 0; inode->i_gid = 0; } - inode->i_mode &= ~(S_ISUID | S_ISGID); security_task_to_inode(task, inode); put_task_struct(task); return 1; @@ -1529,11 +1538,13 @@ static struct file_operations proc_task_ */ static struct inode_operations proc_fd_inode_operations = { .lookup = proc_lookupfd, + .setattr = proc_setattr, }; static struct inode_operations proc_task_inode_operations = { .lookup = proc_task_lookup, .getattr = proc_task_getattr, + .setattr = proc_setattr, }; #ifdef CONFIG_SECURITY @@ -1847,11 +1858,13 @@ static struct file_operations proc_tid_b static struct inode_operations proc_tgid_base_inode_operations = { .lookup = proc_tgid_base_lookup, .getattr = pid_getattr, + .setattr = proc_setattr, }; static struct inode_operations proc_tid_base_inode_operations = { .lookup = proc_tid_base_lookup, .getattr = pid_getattr, + .setattr = proc_setattr, }; #ifdef CONFIG_SECURITY @@ -1894,11 +1907,13 @@ static struct dentry *proc_tid_attr_look static struct inode_operations proc_tgid_attr_inode_operations = { .lookup = proc_tgid_attr_lookup, .getattr = pid_getattr, + .setattr = proc_setattr, }; static struct inode_operations proc_tid_attr_inode_operations = { .lookup = proc_tid_attr_lookup, .getattr = pid_getattr, + .setattr = proc_setattr, }; #endif