summaryrefslogtreecommitdiffstats
path: root/fs/kernfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 21:48:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 21:48:09 -0400
commitf72dae20891d7bcc43e9263ab206960b6ae5209f (patch)
tree59a5b8c026adad15855d3824d1a7014468033274 /fs/kernfs/inode.c
parent498e8631f27ed649bd3e31998a00b2b9b288cf3a (diff)
parent35a196bef449b5824033865b963ed9a43fb8c730 (diff)
Merge tag 'selinux-pr-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: "We've got a few SELinux patches for the v5.2 merge window, the highlights are below: - Add LSM hooks, and the SELinux implementation, for proper labeling of kernfs. While we are only including the SELinux implementation here, the rest of the LSM folks have given the hooks a thumbs-up. - Update the SELinux mdp (Make Dummy Policy) script to actually work on a modern system. - Disallow userspace to change the LSM credentials via /proc/self/attr when the task's credentials are already overridden. The change was made in procfs because all the LSM folks agreed this was the Right Thing To Do and duplicating it across each LSM was going to be annoying" * tag 'selinux-pr-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: proc: prevent changes to overridden credentials selinux: Check address length before reading address family kernfs: fix xattr name handling in LSM helpers MAINTAINERS: update SELinux file patterns selinux: avoid uninitialized variable warning selinux: remove useless assignments LSM: lsm_hooks.h - fix missing colon in docstring selinux: Make selinux_kernfs_init_security static kernfs: initialize security of newly created nodes selinux: implement the kernfs_init_security hook LSM: add new hook for kernfs node initialization kernfs: use simple_xattrs for security attributes selinux: try security xattr after genfs for kernfs filesystems kernfs: do not alloc iattrs in kernfs_xattr_get kernfs: clean up struct kernfs_iattrs scripts/selinux: fix build selinux: use kernel linux/socket.h for genheaders and mdp scripts/selinux: modernize mdp
Diffstat (limited to 'fs/kernfs/inode.c')
-rw-r--r--fs/kernfs/inode.c162
1 files changed, 62 insertions, 100 deletions
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 0c1fd945ce42..f89a0f13840e 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -31,30 +31,27 @@ static const struct inode_operations kernfs_iops = {
31 .listxattr = kernfs_iop_listxattr, 31 .listxattr = kernfs_iop_listxattr,
32}; 32};
33 33
34static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) 34static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, int alloc)
35{ 35{
36 static DEFINE_MUTEX(iattr_mutex); 36 static DEFINE_MUTEX(iattr_mutex);
37 struct kernfs_iattrs *ret; 37 struct kernfs_iattrs *ret;
38 struct iattr *iattrs;
39 38
40 mutex_lock(&iattr_mutex); 39 mutex_lock(&iattr_mutex);
41 40
42 if (kn->iattr) 41 if (kn->iattr || !alloc)
43 goto out_unlock; 42 goto out_unlock;
44 43
45 kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL); 44 kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL);
46 if (!kn->iattr) 45 if (!kn->iattr)
47 goto out_unlock; 46 goto out_unlock;
48 iattrs = &kn->iattr->ia_iattr;
49 47
50 /* assign default attributes */ 48 /* assign default attributes */
51 iattrs->ia_mode = kn->mode; 49 kn->iattr->ia_uid = GLOBAL_ROOT_UID;
52 iattrs->ia_uid = GLOBAL_ROOT_UID; 50 kn->iattr->ia_gid = GLOBAL_ROOT_GID;
53 iattrs->ia_gid = GLOBAL_ROOT_GID;
54 51
55 ktime_get_real_ts64(&iattrs->ia_atime); 52 ktime_get_real_ts64(&kn->iattr->ia_atime);
56 iattrs->ia_mtime = iattrs->ia_atime; 53 kn->iattr->ia_mtime = kn->iattr->ia_atime;
57 iattrs->ia_ctime = iattrs->ia_atime; 54 kn->iattr->ia_ctime = kn->iattr->ia_atime;
58 55
59 simple_xattrs_init(&kn->iattr->xattrs); 56 simple_xattrs_init(&kn->iattr->xattrs);
60out_unlock: 57out_unlock:
@@ -63,32 +60,37 @@ out_unlock:
63 return ret; 60 return ret;
64} 61}
65 62
63static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
64{
65 return __kernfs_iattrs(kn, 1);
66}
67
68static struct kernfs_iattrs *kernfs_iattrs_noalloc(struct kernfs_node *kn)
69{
70 return __kernfs_iattrs(kn, 0);
71}
72
66int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) 73int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
67{ 74{
68 struct kernfs_iattrs *attrs; 75 struct kernfs_iattrs *attrs;
69 struct iattr *iattrs;
70 unsigned int ia_valid = iattr->ia_valid; 76 unsigned int ia_valid = iattr->ia_valid;
71 77
72 attrs = kernfs_iattrs(kn); 78 attrs = kernfs_iattrs(kn);
73 if (!attrs) 79 if (!attrs)
74 return -ENOMEM; 80 return -ENOMEM;
75 81
76 iattrs = &attrs->ia_iattr;
77
78 if (ia_valid & ATTR_UID) 82 if (ia_valid & ATTR_UID)
79 iattrs->ia_uid = iattr->ia_uid; 83 attrs->ia_uid = iattr->ia_uid;
80 if (ia_valid & ATTR_GID) 84 if (ia_valid & ATTR_GID)
81 iattrs->ia_gid = iattr->ia_gid; 85 attrs->ia_gid = iattr->ia_gid;
82 if (ia_valid & ATTR_ATIME) 86 if (ia_valid & ATTR_ATIME)
83 iattrs->ia_atime = iattr->ia_atime; 87 attrs->ia_atime = iattr->ia_atime;
84 if (ia_valid & ATTR_MTIME) 88 if (ia_valid & ATTR_MTIME)
85 iattrs->ia_mtime = iattr->ia_mtime; 89 attrs->ia_mtime = iattr->ia_mtime;
86 if (ia_valid & ATTR_CTIME) 90 if (ia_valid & ATTR_CTIME)
87 iattrs->ia_ctime = iattr->ia_ctime; 91 attrs->ia_ctime = iattr->ia_ctime;
88 if (ia_valid & ATTR_MODE) { 92 if (ia_valid & ATTR_MODE)
89 umode_t mode = iattr->ia_mode; 93 kn->mode = iattr->ia_mode;
90 iattrs->ia_mode = kn->mode = mode;
91 }
92 return 0; 94 return 0;
93} 95}
94 96
@@ -135,23 +137,6 @@ out:
135 return error; 137 return error;
136} 138}
137 139
138static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata,
139 u32 *secdata_len)
140{
141 void *old_secdata;
142 size_t old_secdata_len;
143
144 old_secdata = attrs->ia_secdata;
145 old_secdata_len = attrs->ia_secdata_len;
146
147 attrs->ia_secdata = *secdata;
148 attrs->ia_secdata_len = *secdata_len;
149
150 *secdata = old_secdata;
151 *secdata_len = old_secdata_len;
152 return 0;
153}
154
155ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) 140ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
156{ 141{
157 struct kernfs_node *kn = kernfs_dentry_node(dentry); 142 struct kernfs_node *kn = kernfs_dentry_node(dentry);
@@ -171,14 +156,15 @@ static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
171 inode->i_ctime = current_time(inode); 156 inode->i_ctime = current_time(inode);
172} 157}
173 158
174static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) 159static inline void set_inode_attr(struct inode *inode,
160 struct kernfs_iattrs *attrs)
175{ 161{
176 struct super_block *sb = inode->i_sb; 162 struct super_block *sb = inode->i_sb;
177 inode->i_uid = iattr->ia_uid; 163 inode->i_uid = attrs->ia_uid;
178 inode->i_gid = iattr->ia_gid; 164 inode->i_gid = attrs->ia_gid;
179 inode->i_atime = timespec64_trunc(iattr->ia_atime, sb->s_time_gran); 165 inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran);
180 inode->i_mtime = timespec64_trunc(iattr->ia_mtime, sb->s_time_gran); 166 inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran);
181 inode->i_ctime = timespec64_trunc(iattr->ia_ctime, sb->s_time_gran); 167 inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran);
182} 168}
183 169
184static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) 170static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
@@ -186,15 +172,12 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
186 struct kernfs_iattrs *attrs = kn->iattr; 172 struct kernfs_iattrs *attrs = kn->iattr;
187 173
188 inode->i_mode = kn->mode; 174 inode->i_mode = kn->mode;
189 if (attrs) { 175 if (attrs)
190 /* 176 /*
191 * kernfs_node has non-default attributes get them from 177 * kernfs_node has non-default attributes get them from
192 * persistent copy in kernfs_node. 178 * persistent copy in kernfs_node.
193 */ 179 */
194 set_inode_attr(inode, &attrs->ia_iattr); 180 set_inode_attr(inode, attrs);
195 security_inode_notifysecctx(inode, attrs->ia_secdata,
196 attrs->ia_secdata_len);
197 }
198 181
199 if (kernfs_type(kn) == KERNFS_DIR) 182 if (kernfs_type(kn) == KERNFS_DIR)
200 set_nlink(inode, kn->dir.subdirs + 2); 183 set_nlink(inode, kn->dir.subdirs + 2);
@@ -305,78 +288,57 @@ int kernfs_iop_permission(struct inode *inode, int mask)
305 return generic_permission(inode, mask); 288 return generic_permission(inode, mask);
306} 289}
307 290
308static int kernfs_xattr_get(const struct xattr_handler *handler, 291int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
309 struct dentry *unused, struct inode *inode, 292 void *value, size_t size)
310 const char *suffix, void *value, size_t size)
311{ 293{
312 const char *name = xattr_full_name(handler, suffix); 294 struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn);
313 struct kernfs_node *kn = inode->i_private;
314 struct kernfs_iattrs *attrs;
315
316 attrs = kernfs_iattrs(kn);
317 if (!attrs) 295 if (!attrs)
318 return -ENOMEM; 296 return -ENODATA;
319 297
320 return simple_xattr_get(&attrs->xattrs, name, value, size); 298 return simple_xattr_get(&attrs->xattrs, name, value, size);
321} 299}
322 300
323static int kernfs_xattr_set(const struct xattr_handler *handler, 301int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
324 struct dentry *unused, struct inode *inode, 302 const void *value, size_t size, int flags)
325 const char *suffix, const void *value,
326 size_t size, int flags)
327{ 303{
328 const char *name = xattr_full_name(handler, suffix); 304 struct kernfs_iattrs *attrs = kernfs_iattrs(kn);
329 struct kernfs_node *kn = inode->i_private;
330 struct kernfs_iattrs *attrs;
331
332 attrs = kernfs_iattrs(kn);
333 if (!attrs) 305 if (!attrs)
334 return -ENOMEM; 306 return -ENOMEM;
335 307
336 return simple_xattr_set(&attrs->xattrs, name, value, size, flags); 308 return simple_xattr_set(&attrs->xattrs, name, value, size, flags);
337} 309}
338 310
339static const struct xattr_handler kernfs_trusted_xattr_handler = { 311static int kernfs_vfs_xattr_get(const struct xattr_handler *handler,
340 .prefix = XATTR_TRUSTED_PREFIX, 312 struct dentry *unused, struct inode *inode,
341 .get = kernfs_xattr_get, 313 const char *suffix, void *value, size_t size)
342 .set = kernfs_xattr_set,
343};
344
345static int kernfs_security_xattr_set(const struct xattr_handler *handler,
346 struct dentry *unused, struct inode *inode,
347 const char *suffix, const void *value,
348 size_t size, int flags)
349{ 314{
315 const char *name = xattr_full_name(handler, suffix);
350 struct kernfs_node *kn = inode->i_private; 316 struct kernfs_node *kn = inode->i_private;
351 struct kernfs_iattrs *attrs;
352 void *secdata;
353 u32 secdata_len = 0;
354 int error;
355
356 attrs = kernfs_iattrs(kn);
357 if (!attrs)
358 return -ENOMEM;
359 317
360 error = security_inode_setsecurity(inode, suffix, value, size, flags); 318 return kernfs_xattr_get(kn, name, value, size);
361 if (error) 319}
362 return error;
363 error = security_inode_getsecctx(inode, &secdata, &secdata_len);
364 if (error)
365 return error;
366 320
367 mutex_lock(&kernfs_mutex); 321static int kernfs_vfs_xattr_set(const struct xattr_handler *handler,
368 error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); 322 struct dentry *unused, struct inode *inode,
369 mutex_unlock(&kernfs_mutex); 323 const char *suffix, const void *value,
324 size_t size, int flags)
325{
326 const char *name = xattr_full_name(handler, suffix);
327 struct kernfs_node *kn = inode->i_private;
370 328
371 if (secdata) 329 return kernfs_xattr_set(kn, name, value, size, flags);
372 security_release_secctx(secdata, secdata_len);
373 return error;
374} 330}
375 331
332static const struct xattr_handler kernfs_trusted_xattr_handler = {
333 .prefix = XATTR_TRUSTED_PREFIX,
334 .get = kernfs_vfs_xattr_get,
335 .set = kernfs_vfs_xattr_set,
336};
337
376static const struct xattr_handler kernfs_security_xattr_handler = { 338static const struct xattr_handler kernfs_security_xattr_handler = {
377 .prefix = XATTR_SECURITY_PREFIX, 339 .prefix = XATTR_SECURITY_PREFIX,
378 .get = kernfs_xattr_get, 340 .get = kernfs_vfs_xattr_get,
379 .set = kernfs_security_xattr_set, 341 .set = kernfs_vfs_xattr_set,
380}; 342};
381 343
382const struct xattr_handler *kernfs_xattr_handlers[] = { 344const struct xattr_handler *kernfs_xattr_handlers[] = {