summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/kernfs/inode.c48
-rw-r--r--include/linux/kernfs.h15
-rw-r--r--include/linux/lsm_hooks.h13
-rw-r--r--include/linux/security.h9
-rw-r--r--security/security.c6
5 files changed, 82 insertions, 9 deletions
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index a365088caa3c..673ef598d97d 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -288,12 +288,11 @@ int kernfs_iop_permission(struct inode *inode, int mask)
288 return generic_permission(inode, mask); 288 return generic_permission(inode, mask);
289} 289}
290 290
291static int kernfs_xattr_get(const struct xattr_handler *handler, 291static int kernfs_node_xattr_get(const struct xattr_handler *handler,
292 struct dentry *unused, struct inode *inode, 292 struct kernfs_node *kn, const char *suffix,
293 const char *suffix, void *value, size_t size) 293 void *value, size_t size)
294{ 294{
295 const char *name = xattr_full_name(handler, suffix); 295 const char *name = xattr_full_name(handler, suffix);
296 struct kernfs_node *kn = inode->i_private;
297 struct kernfs_iattrs *attrs; 296 struct kernfs_iattrs *attrs;
298 297
299 attrs = kernfs_iattrs_noalloc(kn); 298 attrs = kernfs_iattrs_noalloc(kn);
@@ -303,13 +302,11 @@ static int kernfs_xattr_get(const struct xattr_handler *handler,
303 return simple_xattr_get(&attrs->xattrs, name, value, size); 302 return simple_xattr_get(&attrs->xattrs, name, value, size);
304} 303}
305 304
306static int kernfs_xattr_set(const struct xattr_handler *handler, 305static int kernfs_node_xattr_set(const struct xattr_handler *handler,
307 struct dentry *unused, struct inode *inode, 306 struct kernfs_node *kn, const char *suffix,
308 const char *suffix, const void *value, 307 const void *value, size_t size, int flags)
309 size_t size, int flags)
310{ 308{
311 const char *name = xattr_full_name(handler, suffix); 309 const char *name = xattr_full_name(handler, suffix);
312 struct kernfs_node *kn = inode->i_private;
313 struct kernfs_iattrs *attrs; 310 struct kernfs_iattrs *attrs;
314 311
315 attrs = kernfs_iattrs(kn); 312 attrs = kernfs_iattrs(kn);
@@ -319,6 +316,25 @@ static int kernfs_xattr_set(const struct xattr_handler *handler,
319 return simple_xattr_set(&attrs->xattrs, name, value, size, flags); 316 return simple_xattr_set(&attrs->xattrs, name, value, size, flags);
320} 317}
321 318
319static int kernfs_xattr_get(const struct xattr_handler *handler,
320 struct dentry *unused, struct inode *inode,
321 const char *suffix, void *value, size_t size)
322{
323 struct kernfs_node *kn = inode->i_private;
324
325 return kernfs_node_xattr_get(handler, kn, suffix, value, size);
326}
327
328static int kernfs_xattr_set(const struct xattr_handler *handler,
329 struct dentry *unused, struct inode *inode,
330 const char *suffix, const void *value,
331 size_t size, int flags)
332{
333 struct kernfs_node *kn = inode->i_private;
334
335 return kernfs_node_xattr_set(handler, kn, suffix, value, size, flags);
336}
337
322static const struct xattr_handler kernfs_trusted_xattr_handler = { 338static const struct xattr_handler kernfs_trusted_xattr_handler = {
323 .prefix = XATTR_TRUSTED_PREFIX, 339 .prefix = XATTR_TRUSTED_PREFIX,
324 .get = kernfs_xattr_get, 340 .get = kernfs_xattr_get,
@@ -336,3 +352,17 @@ const struct xattr_handler *kernfs_xattr_handlers[] = {
336 &kernfs_security_xattr_handler, 352 &kernfs_security_xattr_handler,
337 NULL 353 NULL
338}; 354};
355
356int kernfs_security_xattr_get(struct kernfs_node *kn, const char *suffix,
357 void *value, size_t size)
358{
359 return kernfs_node_xattr_get(&kernfs_security_xattr_handler,
360 kn, suffix, value, size);
361}
362
363int kernfs_security_xattr_set(struct kernfs_node *kn, const char *suffix,
364 void *value, size_t size, int flags)
365{
366 return kernfs_node_xattr_set(&kernfs_security_xattr_handler,
367 kn, suffix, value, size, flags);
368}
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index c8893f663470..39eea07c2900 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -371,6 +371,11 @@ __poll_t kernfs_generic_poll(struct kernfs_open_file *of,
371 struct poll_table_struct *pt); 371 struct poll_table_struct *pt);
372void kernfs_notify(struct kernfs_node *kn); 372void kernfs_notify(struct kernfs_node *kn);
373 373
374int kernfs_security_xattr_get(struct kernfs_node *kn, const char *suffix,
375 void *value, size_t size);
376int kernfs_security_xattr_set(struct kernfs_node *kn, const char *suffix,
377 void *value, size_t size, int flags);
378
374const void *kernfs_super_ns(struct super_block *sb); 379const void *kernfs_super_ns(struct super_block *sb);
375int kernfs_get_tree(struct fs_context *fc); 380int kernfs_get_tree(struct fs_context *fc);
376void kernfs_free_fs_context(struct fs_context *fc); 381void kernfs_free_fs_context(struct fs_context *fc);
@@ -473,6 +478,16 @@ static inline int kernfs_setattr(struct kernfs_node *kn,
473 478
474static inline void kernfs_notify(struct kernfs_node *kn) { } 479static inline void kernfs_notify(struct kernfs_node *kn) { }
475 480
481static inline int kernfs_security_xattr_get(struct kernfs_node *kn,
482 const char *suffix, void *value,
483 size_t size)
484{ return -ENOSYS; }
485
486static inline int kernfs_security_xattr_set(struct kernfs_node *kn,
487 const char *suffix, void *value,
488 size_t size, int flags)
489{ return -ENOSYS; }
490
476static inline const void *kernfs_super_ns(struct super_block *sb) 491static inline const void *kernfs_super_ns(struct super_block *sb)
477{ return NULL; } 492{ return NULL; }
478 493
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index a9b8ff578b6b..0dd5bda719e6 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -445,6 +445,15 @@
445 * to abort the copy up. Note that the caller is responsible for reading 445 * to abort the copy up. Note that the caller is responsible for reading
446 * and writing the xattrs as this hook is merely a filter. 446 * and writing the xattrs as this hook is merely a filter.
447 * 447 *
448 * Security hooks for kernfs node operations
449 *
450 * @kernfs_init_security
451 * Initialize the security context of a newly created kernfs node based
452 * on its own and its parent's attributes.
453 *
454 * @kn_dir the parent kernfs node
455 * @kn the new child kernfs node
456 *
448 * Security hooks for file operations 457 * Security hooks for file operations
449 * 458 *
450 * @file_permission: 459 * @file_permission:
@@ -1578,6 +1587,9 @@ union security_list_options {
1578 int (*inode_copy_up)(struct dentry *src, struct cred **new); 1587 int (*inode_copy_up)(struct dentry *src, struct cred **new);
1579 int (*inode_copy_up_xattr)(const char *name); 1588 int (*inode_copy_up_xattr)(const char *name);
1580 1589
1590 int (*kernfs_init_security)(struct kernfs_node *kn_dir,
1591 struct kernfs_node *kn);
1592
1581 int (*file_permission)(struct file *file, int mask); 1593 int (*file_permission)(struct file *file, int mask);
1582 int (*file_alloc_security)(struct file *file); 1594 int (*file_alloc_security)(struct file *file);
1583 void (*file_free_security)(struct file *file); 1595 void (*file_free_security)(struct file *file);
@@ -1879,6 +1891,7 @@ struct security_hook_heads {
1879 struct hlist_head inode_getsecid; 1891 struct hlist_head inode_getsecid;
1880 struct hlist_head inode_copy_up; 1892 struct hlist_head inode_copy_up;
1881 struct hlist_head inode_copy_up_xattr; 1893 struct hlist_head inode_copy_up_xattr;
1894 struct hlist_head kernfs_init_security;
1882 struct hlist_head file_permission; 1895 struct hlist_head file_permission;
1883 struct hlist_head file_alloc_security; 1896 struct hlist_head file_alloc_security;
1884 struct hlist_head file_free_security; 1897 struct hlist_head file_free_security;
diff --git a/include/linux/security.h b/include/linux/security.h
index 49f2685324b0..d543293216b9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -51,6 +51,7 @@ struct fown_struct;
51struct file_operations; 51struct file_operations;
52struct msg_msg; 52struct msg_msg;
53struct xattr; 53struct xattr;
54struct kernfs_node;
54struct xfrm_sec_ctx; 55struct xfrm_sec_ctx;
55struct mm_struct; 56struct mm_struct;
56struct fs_context; 57struct fs_context;
@@ -299,6 +300,8 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
299void security_inode_getsecid(struct inode *inode, u32 *secid); 300void security_inode_getsecid(struct inode *inode, u32 *secid);
300int security_inode_copy_up(struct dentry *src, struct cred **new); 301int security_inode_copy_up(struct dentry *src, struct cred **new);
301int security_inode_copy_up_xattr(const char *name); 302int security_inode_copy_up_xattr(const char *name);
303int security_kernfs_init_security(struct kernfs_node *kn_dir,
304 struct kernfs_node *kn);
302int security_file_permission(struct file *file, int mask); 305int security_file_permission(struct file *file, int mask);
303int security_file_alloc(struct file *file); 306int security_file_alloc(struct file *file);
304void security_file_free(struct file *file); 307void security_file_free(struct file *file);
@@ -801,6 +804,12 @@ static inline int security_inode_copy_up(struct dentry *src, struct cred **new)
801 return 0; 804 return 0;
802} 805}
803 806
807static inline int security_kernfs_init_security(struct kernfs_node *kn_dir,
808 struct kernfs_node *kn)
809{
810 return 0;
811}
812
804static inline int security_inode_copy_up_xattr(const char *name) 813static inline int security_inode_copy_up_xattr(const char *name)
805{ 814{
806 return -EOPNOTSUPP; 815 return -EOPNOTSUPP;
diff --git a/security/security.c b/security/security.c
index 23cbb1a295a3..8d6ef9da94eb 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1318,6 +1318,12 @@ int security_inode_copy_up_xattr(const char *name)
1318} 1318}
1319EXPORT_SYMBOL(security_inode_copy_up_xattr); 1319EXPORT_SYMBOL(security_inode_copy_up_xattr);
1320 1320
1321int security_kernfs_init_security(struct kernfs_node *kn_dir,
1322 struct kernfs_node *kn)
1323{
1324 return call_int_hook(kernfs_init_security, 0, kn_dir, kn);
1325}
1326
1321int security_file_permission(struct file *file, int mask) 1327int security_file_permission(struct file *file, int mask)
1322{ 1328{
1323 int ret; 1329 int ret;