diff --git a/fs/proc/base.c b/fs/proc/base.c index ec158dd02b3ac2b758fbbf527820c1f0f83a486a..a721acfd4fdcd3a008befe2a8a185a863b5e0903 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1447,11 +1447,29 @@ static const struct file_operations proc_fd_operations = { .readdir = proc_readfd, }; +/* + * /proc/pid/fd needs a special permission handler so that a process can still + * access /proc/self/fd after it has executed a setuid(). + */ +static int proc_fd_permission(struct inode *inode, int mask, + struct nameidata *nd) +{ + int rv; + + rv = generic_permission(inode, mask, NULL); + if (rv == 0) + return 0; + if (task_pid(current) == proc_pid(inode)) + rv = 0; + return rv; +} + /* * proc directories can do almost nothing.. */ static const struct inode_operations proc_fd_inode_operations = { .lookup = proc_lookupfd, + .permission = proc_fd_permission, .setattr = proc_setattr, };