aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index fee804e69a9a..80eca7d3d69f 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -20,6 +20,47 @@
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21 21
22 22
23/*
24 * Check permissions for extended attribute access. This is a bit complicated
25 * because different namespaces have very different rules.
26 */
27static int
28xattr_permission(struct inode *inode, const char *name, int mask)
29{
30 /*
31 * We can never set or remove an extended attribute on a read-only
32 * filesystem or on an immutable / append-only inode.
33 */
34 if (mask & MAY_WRITE) {
35 if (IS_RDONLY(inode))
36 return -EROFS;
37 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
38 return -EPERM;
39 }
40
41 /*
42 * No restriction for security.* and system.* from the VFS. Decision
43 * on these is left to the underlying filesystem / security module.
44 */
45 if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
46 !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
47 return 0;
48
49 /*
50 * The trusted.* namespace can only accessed by a privilegued user.
51 */
52 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
53 return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
54
55 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
56 if (!S_ISREG(inode->i_mode) &&
57 (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
58 return -EPERM;
59 }
60
61 return permission(inode, mask, NULL);
62}
63
23int 64int
24vfs_setxattr(struct dentry *dentry, char *name, void *value, 65vfs_setxattr(struct dentry *dentry, char *name, void *value,
25 size_t size, int flags) 66 size_t size, int flags)
@@ -27,6 +68,10 @@ vfs_setxattr(struct dentry *dentry, char *name, void *value,
27 struct inode *inode = dentry->d_inode; 68 struct inode *inode = dentry->d_inode;
28 int error; 69 int error;
29 70
71 error = xattr_permission(inode, name, MAY_WRITE);
72 if (error)
73 return error;
74
30 mutex_lock(&inode->i_mutex); 75 mutex_lock(&inode->i_mutex);
31 error = security_inode_setxattr(dentry, name, value, size, flags); 76 error = security_inode_setxattr(dentry, name, value, size, flags);
32 if (error) 77 if (error)
@@ -40,8 +85,8 @@ vfs_setxattr(struct dentry *dentry, char *name, void *value,
40 size, flags); 85 size, flags);
41 } 86 }
42 } else if (!strncmp(name, XATTR_SECURITY_PREFIX, 87 } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
43 sizeof XATTR_SECURITY_PREFIX - 1)) { 88 XATTR_SECURITY_PREFIX_LEN)) {
44 const char *suffix = name + sizeof XATTR_SECURITY_PREFIX - 1; 89 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
45 error = security_inode_setsecurity(inode, suffix, value, 90 error = security_inode_setsecurity(inode, suffix, value,
46 size, flags); 91 size, flags);
47 if (!error) 92 if (!error)
@@ -59,6 +104,10 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
59 struct inode *inode = dentry->d_inode; 104 struct inode *inode = dentry->d_inode;
60 int error; 105 int error;
61 106
107 error = xattr_permission(inode, name, MAY_READ);
108 if (error)
109 return error;
110
62 error = security_inode_getxattr(dentry, name); 111 error = security_inode_getxattr(dentry, name);
63 if (error) 112 if (error)
64 return error; 113 return error;
@@ -69,8 +118,8 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
69 error = -EOPNOTSUPP; 118 error = -EOPNOTSUPP;
70 119
71 if (!strncmp(name, XATTR_SECURITY_PREFIX, 120 if (!strncmp(name, XATTR_SECURITY_PREFIX,
72 sizeof XATTR_SECURITY_PREFIX - 1)) { 121 XATTR_SECURITY_PREFIX_LEN)) {
73 const char *suffix = name + sizeof XATTR_SECURITY_PREFIX - 1; 122 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
74 int ret = security_inode_getsecurity(inode, suffix, value, 123 int ret = security_inode_getsecurity(inode, suffix, value,
75 size, error); 124 size, error);
76 /* 125 /*
@@ -94,6 +143,10 @@ vfs_removexattr(struct dentry *dentry, char *name)
94 if (!inode->i_op->removexattr) 143 if (!inode->i_op->removexattr)
95 return -EOPNOTSUPP; 144 return -EOPNOTSUPP;
96 145
146 error = xattr_permission(inode, name, MAY_WRITE);
147 if (error)
148 return error;
149
97 error = security_inode_removexattr(dentry, name); 150 error = security_inode_removexattr(dentry, name);
98 if (error) 151 if (error)
99 return error; 152 return error;