diff options
Diffstat (limited to 'fs/attr.c')
-rw-r--r-- | fs/attr.c | 36 |
1 files changed, 28 insertions, 8 deletions
@@ -18,6 +18,32 @@ | |||
18 | #include <linux/evm.h> | 18 | #include <linux/evm.h> |
19 | #include <linux/ima.h> | 19 | #include <linux/ima.h> |
20 | 20 | ||
21 | static bool chown_ok(const struct inode *inode, kuid_t uid) | ||
22 | { | ||
23 | if (uid_eq(current_fsuid(), inode->i_uid) && | ||
24 | uid_eq(uid, inode->i_uid)) | ||
25 | return true; | ||
26 | if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) | ||
27 | return true; | ||
28 | if (uid_eq(inode->i_uid, INVALID_UID) && | ||
29 | ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN)) | ||
30 | return true; | ||
31 | return false; | ||
32 | } | ||
33 | |||
34 | static bool chgrp_ok(const struct inode *inode, kgid_t gid) | ||
35 | { | ||
36 | if (uid_eq(current_fsuid(), inode->i_uid) && | ||
37 | (in_group_p(gid) || gid_eq(gid, inode->i_gid))) | ||
38 | return true; | ||
39 | if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) | ||
40 | return true; | ||
41 | if (gid_eq(inode->i_gid, INVALID_GID) && | ||
42 | ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN)) | ||
43 | return true; | ||
44 | return false; | ||
45 | } | ||
46 | |||
21 | /** | 47 | /** |
22 | * setattr_prepare - check if attribute changes to a dentry are allowed | 48 | * setattr_prepare - check if attribute changes to a dentry are allowed |
23 | * @dentry: dentry to check | 49 | * @dentry: dentry to check |
@@ -52,17 +78,11 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr) | |||
52 | goto kill_priv; | 78 | goto kill_priv; |
53 | 79 | ||
54 | /* Make sure a caller can chown. */ | 80 | /* Make sure a caller can chown. */ |
55 | if ((ia_valid & ATTR_UID) && | 81 | if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid)) |
56 | (!uid_eq(current_fsuid(), inode->i_uid) || | ||
57 | !uid_eq(attr->ia_uid, inode->i_uid)) && | ||
58 | !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) | ||
59 | return -EPERM; | 82 | return -EPERM; |
60 | 83 | ||
61 | /* Make sure caller can chgrp. */ | 84 | /* Make sure caller can chgrp. */ |
62 | if ((ia_valid & ATTR_GID) && | 85 | if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid)) |
63 | (!uid_eq(current_fsuid(), inode->i_uid) || | ||
64 | (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && | ||
65 | !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) | ||
66 | return -EPERM; | 86 | return -EPERM; |
67 | 87 | ||
68 | /* Make sure a caller can chmod. */ | 88 | /* Make sure a caller can chmod. */ |