aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/inode.c')
-rw-r--r--fs/sysfs/inode.c134
1 files changed, 98 insertions, 36 deletions
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 555f0ff988df..2b6a8d9de73d 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -18,6 +18,8 @@
18#include <linux/capability.h> 18#include <linux/capability.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/xattr.h>
22#include <linux/security.h>
21#include "sysfs.h" 23#include "sysfs.h"
22 24
23extern struct super_block * sysfs_sb; 25extern struct super_block * sysfs_sb;
@@ -35,6 +37,7 @@ static struct backing_dev_info sysfs_backing_dev_info = {
35 37
36static const struct inode_operations sysfs_inode_operations ={ 38static const struct inode_operations sysfs_inode_operations ={
37 .setattr = sysfs_setattr, 39 .setattr = sysfs_setattr,
40 .setxattr = sysfs_setxattr,
38}; 41};
39 42
40int __init sysfs_inode_init(void) 43int __init sysfs_inode_init(void)
@@ -42,18 +45,37 @@ int __init sysfs_inode_init(void)
42 return bdi_init(&sysfs_backing_dev_info); 45 return bdi_init(&sysfs_backing_dev_info);
43} 46}
44 47
48struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
49{
50 struct sysfs_inode_attrs *attrs;
51 struct iattr *iattrs;
52
53 attrs = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL);
54 if (!attrs)
55 return NULL;
56 iattrs = &attrs->ia_iattr;
57
58 /* assign default attributes */
59 iattrs->ia_mode = sd->s_mode;
60 iattrs->ia_uid = 0;
61 iattrs->ia_gid = 0;
62 iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
63
64 return attrs;
65}
45int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) 66int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
46{ 67{
47 struct inode * inode = dentry->d_inode; 68 struct inode * inode = dentry->d_inode;
48 struct sysfs_dirent * sd = dentry->d_fsdata; 69 struct sysfs_dirent * sd = dentry->d_fsdata;
49 struct iattr * sd_iattr; 70 struct sysfs_inode_attrs *sd_attrs;
71 struct iattr *iattrs;
50 unsigned int ia_valid = iattr->ia_valid; 72 unsigned int ia_valid = iattr->ia_valid;
51 int error; 73 int error;
52 74
53 if (!sd) 75 if (!sd)
54 return -EINVAL; 76 return -EINVAL;
55 77
56 sd_iattr = sd->s_iattr; 78 sd_attrs = sd->s_iattr;
57 79
58 error = inode_change_ok(inode, iattr); 80 error = inode_change_ok(inode, iattr);
59 if (error) 81 if (error)
@@ -65,42 +87,77 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
65 if (error) 87 if (error)
66 return error; 88 return error;
67 89
68 if (!sd_iattr) { 90 if (!sd_attrs) {
69 /* setting attributes for the first time, allocate now */ 91 /* setting attributes for the first time, allocate now */
70 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); 92 sd_attrs = sysfs_init_inode_attrs(sd);
71 if (!sd_iattr) 93 if (!sd_attrs)
72 return -ENOMEM; 94 return -ENOMEM;
73 /* assign default attributes */ 95 sd->s_iattr = sd_attrs;
74 sd_iattr->ia_mode = sd->s_mode; 96 } else {
75 sd_iattr->ia_uid = 0; 97 /* attributes were changed at least once in past */
76 sd_iattr->ia_gid = 0; 98 iattrs = &sd_attrs->ia_iattr;
77 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; 99
78 sd->s_iattr = sd_iattr; 100 if (ia_valid & ATTR_UID)
101 iattrs->ia_uid = iattr->ia_uid;
102 if (ia_valid & ATTR_GID)
103 iattrs->ia_gid = iattr->ia_gid;
104 if (ia_valid & ATTR_ATIME)
105 iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
106 inode->i_sb->s_time_gran);
107 if (ia_valid & ATTR_MTIME)
108 iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
109 inode->i_sb->s_time_gran);
110 if (ia_valid & ATTR_CTIME)
111 iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
112 inode->i_sb->s_time_gran);
113 if (ia_valid & ATTR_MODE) {
114 umode_t mode = iattr->ia_mode;
115
116 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
117 mode &= ~S_ISGID;
118 iattrs->ia_mode = sd->s_mode = mode;
119 }
79 } 120 }
121 return error;
122}
80 123
81 /* attributes were changed atleast once in past */ 124int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
82 125 size_t size, int flags)
83 if (ia_valid & ATTR_UID) 126{
84 sd_iattr->ia_uid = iattr->ia_uid; 127 struct sysfs_dirent *sd = dentry->d_fsdata;
85 if (ia_valid & ATTR_GID) 128 struct sysfs_inode_attrs *iattrs;
86 sd_iattr->ia_gid = iattr->ia_gid; 129 void *secdata;
87 if (ia_valid & ATTR_ATIME) 130 int error;
88 sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, 131 u32 secdata_len = 0;
89 inode->i_sb->s_time_gran); 132
90 if (ia_valid & ATTR_MTIME) 133 if (!sd)
91 sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, 134 return -EINVAL;
92 inode->i_sb->s_time_gran); 135 if (!sd->s_iattr)
93 if (ia_valid & ATTR_CTIME) 136 sd->s_iattr = sysfs_init_inode_attrs(sd);
94 sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, 137 if (!sd->s_iattr)
95 inode->i_sb->s_time_gran); 138 return -ENOMEM;
96 if (ia_valid & ATTR_MODE) { 139
97 umode_t mode = iattr->ia_mode; 140 iattrs = sd->s_iattr;
98 141
99 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) 142 if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
100 mode &= ~S_ISGID; 143 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
101 sd_iattr->ia_mode = sd->s_mode = mode; 144 error = security_inode_setsecurity(dentry->d_inode, suffix,
102 } 145 value, size, flags);
146 if (error)
147 goto out;
148 error = security_inode_getsecctx(dentry->d_inode,
149 &secdata, &secdata_len);
150 if (error)
151 goto out;
152 if (iattrs->ia_secdata)
153 security_release_secctx(iattrs->ia_secdata,
154 iattrs->ia_secdata_len);
155 iattrs->ia_secdata = secdata;
156 iattrs->ia_secdata_len = secdata_len;
103 157
158 } else
159 return -EINVAL;
160out:
104 return error; 161 return error;
105} 162}
106 163
@@ -146,6 +203,7 @@ static int sysfs_count_nlink(struct sysfs_dirent *sd)
146static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 203static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
147{ 204{
148 struct bin_attribute *bin_attr; 205 struct bin_attribute *bin_attr;
206 struct sysfs_inode_attrs *iattrs;
149 207
150 inode->i_private = sysfs_get(sd); 208 inode->i_private = sysfs_get(sd);
151 inode->i_mapping->a_ops = &sysfs_aops; 209 inode->i_mapping->a_ops = &sysfs_aops;
@@ -154,16 +212,20 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
154 inode->i_ino = sd->s_ino; 212 inode->i_ino = sd->s_ino;
155 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); 213 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
156 214
157 if (sd->s_iattr) { 215 iattrs = sd->s_iattr;
216 if (iattrs) {
158 /* sysfs_dirent has non-default attributes 217 /* sysfs_dirent has non-default attributes
159 * get them for the new inode from persistent copy 218 * get them for the new inode from persistent copy
160 * in sysfs_dirent 219 * in sysfs_dirent
161 */ 220 */
162 set_inode_attr(inode, sd->s_iattr); 221 set_inode_attr(inode, &iattrs->ia_iattr);
222 if (iattrs->ia_secdata)
223 security_inode_notifysecctx(inode,
224 iattrs->ia_secdata,
225 iattrs->ia_secdata_len);
163 } else 226 } else
164 set_default_inode_attr(inode, sd->s_mode); 227 set_default_inode_attr(inode, sd->s_mode);
165 228
166
167 /* initialize inode according to type */ 229 /* initialize inode according to type */
168 switch (sysfs_type(sd)) { 230 switch (sysfs_type(sd)) {
169 case SYSFS_DIR: 231 case SYSFS_DIR: