aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jfs/xattr.c15
-rw-r--r--fs/xattr.c61
-rw-r--r--include/linux/xattr.h15
3 files changed, 72 insertions, 19 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 23aa5066b5a4..9dde36a1eb5d 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -83,21 +83,6 @@ struct ea_buffer {
83#define EA_NEW 0x0004 83#define EA_NEW 0x0004
84#define EA_MALLOC 0x0008 84#define EA_MALLOC 0x0008
85 85
86/* Namespaces */
87#define XATTR_SYSTEM_PREFIX "system."
88#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
89
90#define XATTR_USER_PREFIX "user."
91#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
92
93#define XATTR_OS2_PREFIX "os2."
94#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
95
96/* XATTR_SECURITY_PREFIX is defined in include/linux/xattr.h */
97#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
98
99#define XATTR_TRUSTED_PREFIX "trusted."
100#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
101 86
102/* 87/*
103 * These three routines are used to recognize on-disk extended attributes 88 * These three routines are used to recognize on-disk extended attributes
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;
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 366f0ab4219f..cda8a96e2fa0 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -13,7 +13,22 @@
13#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ 13#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
14#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ 14#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
15 15
16/* Namespaces */
17#define XATTR_OS2_PREFIX "os2."
18#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
19
16#define XATTR_SECURITY_PREFIX "security." 20#define XATTR_SECURITY_PREFIX "security."
21#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
22
23#define XATTR_SYSTEM_PREFIX "system."
24#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
25
26#define XATTR_TRUSTED_PREFIX "trusted."
27#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
28
29#define XATTR_USER_PREFIX "user."
30#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
31
17 32
18struct xattr_handler { 33struct xattr_handler {
19 char *prefix; 34 char *prefix;