Commit 6d76fa58b050044994fe25f8753b8023f2b36737

Authored by Linus Torvalds
1 parent 92d032855e

Don't allow chmod() on the /proc/<pid>/ files

This just turns off chmod() on the /proc/<pid>/ files, since there is no
good reason to allow it, and had we disallowed it originally, the nasty
/proc race exploit wouldn't have been possible.

The other patches already fixed the problem chmod() could cause, so this
is really just some final mop-up..

This particular version is based off a patch by Eugene and Marcel which
had much better naming than my original equivalent one.

Signed-off-by: Eugene Teo <eteo@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 30 additions and 1 deletions Side-by-side Diff

... ... @@ -551,6 +551,27 @@
551 551 return allowed;
552 552 }
553 553  
  554 +static int proc_setattr(struct dentry *dentry, struct iattr *attr)
  555 +{
  556 + int error;
  557 + struct inode *inode = dentry->d_inode;
  558 +
  559 + if (attr->ia_valid & ATTR_MODE)
  560 + return -EPERM;
  561 +
  562 + error = inode_change_ok(inode, attr);
  563 + if (!error) {
  564 + error = security_inode_setattr(dentry, attr);
  565 + if (!error)
  566 + error = inode_setattr(inode, attr);
  567 + }
  568 + return error;
  569 +}
  570 +
  571 +static struct inode_operations proc_def_inode_operations = {
  572 + .setattr = proc_setattr,
  573 +};
  574 +
554 575 extern struct seq_operations mounts_op;
555 576 struct proc_mounts {
556 577 struct seq_file m;
... ... @@ -1111,7 +1132,8 @@
1111 1132  
1112 1133 static struct inode_operations proc_pid_link_inode_operations = {
1113 1134 .readlink = proc_pid_readlink,
1114   - .follow_link = proc_pid_follow_link
  1135 + .follow_link = proc_pid_follow_link,
  1136 + .setattr = proc_setattr,
1115 1137 };
1116 1138  
1117 1139 static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
... ... @@ -1285,6 +1307,7 @@
1285 1307 ei = PROC_I(inode);
1286 1308 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1287 1309 inode->i_ino = fake_ino(task->pid, ino);
  1310 + inode->i_op = &proc_def_inode_operations;
1288 1311  
1289 1312 /*
1290 1313 * grab the reference to task.
1291 1314  
... ... @@ -1529,11 +1552,13 @@
1529 1552 */
1530 1553 static struct inode_operations proc_fd_inode_operations = {
1531 1554 .lookup = proc_lookupfd,
  1555 + .setattr = proc_setattr,
1532 1556 };
1533 1557  
1534 1558 static struct inode_operations proc_task_inode_operations = {
1535 1559 .lookup = proc_task_lookup,
1536 1560 .getattr = proc_task_getattr,
  1561 + .setattr = proc_setattr,
1537 1562 };
1538 1563  
1539 1564 #ifdef CONFIG_SECURITY
1540 1565  
... ... @@ -1847,11 +1872,13 @@
1847 1872 static struct inode_operations proc_tgid_base_inode_operations = {
1848 1873 .lookup = proc_tgid_base_lookup,
1849 1874 .getattr = pid_getattr,
  1875 + .setattr = proc_setattr,
1850 1876 };
1851 1877  
1852 1878 static struct inode_operations proc_tid_base_inode_operations = {
1853 1879 .lookup = proc_tid_base_lookup,
1854 1880 .getattr = pid_getattr,
  1881 + .setattr = proc_setattr,
1855 1882 };
1856 1883  
1857 1884 #ifdef CONFIG_SECURITY
1858 1885  
... ... @@ -1894,11 +1921,13 @@
1894 1921 static struct inode_operations proc_tgid_attr_inode_operations = {
1895 1922 .lookup = proc_tgid_attr_lookup,
1896 1923 .getattr = pid_getattr,
  1924 + .setattr = proc_setattr,
1897 1925 };
1898 1926  
1899 1927 static struct inode_operations proc_tid_attr_inode_operations = {
1900 1928 .lookup = proc_tid_attr_lookup,
1901 1929 .getattr = pid_getattr,
  1930 + .setattr = proc_setattr,
1902 1931 };
1903 1932 #endif
1904 1933