summaryrefslogtreecommitdiff
blob: 1e4ba6f7601a6f57cba870a4f4fe0ce5c39a2e21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/07/02 20:55:04-07:00 chrisw@osdl.org 
#   [PATCH] chown permission check fix for ATTR_GID
#   
#   SuSE discovered this problem with chown and ATTR_GID.  Make sure user
#   is authorized to change the group, CAN-2004-0497.
# 
# fs/attr.c
#   2004/07/02 09:07:32-07:00 chrisw@osdl.org +2 -1
#   chown permission check fix for ATTR_GID
# 
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	2004-07-08 16:35:57 -07:00
+++ b/fs/attr.c	2004-07-08 16:35:57 -07:00
@@ -35,7 +35,8 @@
 
 	/* Make sure caller can chgrp. */
 	if ((ia_valid & ATTR_GID) &&
-	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) &&
+	    (current->fsuid != inode->i_uid ||
+	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
 	    !capable(CAP_CHOWN))
 		goto error;
 
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/07/02 18:48:26-07:00 chrisw@osdl.org 
#   [PATCH] check attr updates in /proc
#   
#   Any proc entry with default proc_file_inode_operations allow unauthorized
#   attribute updates.  This is very dangerous for proc entries that rely
#   solely on file permissions for open/read/write.
#   
#   Signed-off-by: Chris Wright <chrisw@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/proc/generic.c
#   2004/07/02 15:47:55-07:00 chrisw@osdl.org +14 -7
#   check attr updates in /proc
# 
diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c
--- a/fs/proc/generic.c	2004-07-08 17:03:20 -07:00
+++ b/fs/proc/generic.c	2004-07-08 17:03:20 -07:00
@@ -231,14 +231,21 @@
 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
 {
 	struct inode *inode = dentry->d_inode;
-	int error = inode_setattr(inode, iattr);
-	if (!error) {
-		struct proc_dir_entry *de = PDE(inode);
-		de->uid = inode->i_uid;
-		de->gid = inode->i_gid;
-		de->mode = inode->i_mode;
-	}
+	struct proc_dir_entry *de = PDE(inode);
+	int error;
 
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		goto out;
+
+	error = inode_setattr(inode, iattr);
+	if (error)
+		goto out;
+	
+	de->uid = inode->i_uid;
+	de->gid = inode->i_gid;
+	de->mode = inode->i_mode;
+out:
 	return error;
 }