diff options
author | Subodh Nijsure <snijsure@grid-net.com> | 2014-10-31 14:50:30 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-01-28 10:08:54 -0500 |
commit | d7f0b70d30ffb9bbe6b8a3e1035cf0b79965ef53 (patch) | |
tree | a903ee476aad8a9dcff9ef5cd9d4a4626e679990 /fs/ubifs | |
parent | 895d9db253a0b0b1f8a6e635fb2460d80bf72d5a (diff) |
UBIFS: Add security.* XATTR support for the UBIFS
Artem: rename static functions so that they do not use the "ubifs_" prefix - we
only use this prefix for non-static functions.
Artem: remove few junk white-space changes in file.c
Signed-off-by: Subodh Nijsure <snijsure@grid-net.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Ben Shelton <ben.shelton@ni.com>
Acked-by: Brad Mouring <brad.mouring@ni.com>
Acked-by: Terry Wilcox <terry.wilcox@ni.com>
Acked-by: Gratian Crisan <gratian.crisan@ni.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/dir.c | 16 | ||||
-rw-r--r-- | fs/ubifs/super.c | 1 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 4 | ||||
-rw-r--r-- | fs/ubifs/xattr.c | 78 |
4 files changed, 99 insertions, 0 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index ea41649e4ca5..f7e8f765b36f 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -272,6 +272,10 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
272 | goto out_budg; | 272 | goto out_budg; |
273 | } | 273 | } |
274 | 274 | ||
275 | err = ubifs_init_security(dir, inode, &dentry->d_name); | ||
276 | if (err) | ||
277 | goto out_cancel; | ||
278 | |||
275 | mutex_lock(&dir_ui->ui_mutex); | 279 | mutex_lock(&dir_ui->ui_mutex); |
276 | dir->i_size += sz_change; | 280 | dir->i_size += sz_change; |
277 | dir_ui->ui_size = dir->i_size; | 281 | dir_ui->ui_size = dir->i_size; |
@@ -728,6 +732,10 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
728 | goto out_budg; | 732 | goto out_budg; |
729 | } | 733 | } |
730 | 734 | ||
735 | err = ubifs_init_security(dir, inode, &dentry->d_name); | ||
736 | if (err) | ||
737 | goto out_cancel; | ||
738 | |||
731 | mutex_lock(&dir_ui->ui_mutex); | 739 | mutex_lock(&dir_ui->ui_mutex); |
732 | insert_inode_hash(inode); | 740 | insert_inode_hash(inode); |
733 | inc_nlink(inode); | 741 | inc_nlink(inode); |
@@ -808,6 +816,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
808 | ui->data = dev; | 816 | ui->data = dev; |
809 | ui->data_len = devlen; | 817 | ui->data_len = devlen; |
810 | 818 | ||
819 | err = ubifs_init_security(dir, inode, &dentry->d_name); | ||
820 | if (err) | ||
821 | goto out_cancel; | ||
822 | |||
811 | mutex_lock(&dir_ui->ui_mutex); | 823 | mutex_lock(&dir_ui->ui_mutex); |
812 | dir->i_size += sz_change; | 824 | dir->i_size += sz_change; |
813 | dir_ui->ui_size = dir->i_size; | 825 | dir_ui->ui_size = dir->i_size; |
@@ -884,6 +896,10 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, | |||
884 | ui->data_len = len; | 896 | ui->data_len = len; |
885 | inode->i_size = ubifs_inode(inode)->ui_size = len; | 897 | inode->i_size = ubifs_inode(inode)->ui_size = len; |
886 | 898 | ||
899 | err = ubifs_init_security(dir, inode, &dentry->d_name); | ||
900 | if (err) | ||
901 | goto out_cancel; | ||
902 | |||
887 | mutex_lock(&dir_ui->ui_mutex); | 903 | mutex_lock(&dir_ui->ui_mutex); |
888 | dir->i_size += sz_change; | 904 | dir->i_size += sz_change; |
889 | dir_ui->ui_size = dir->i_size; | 905 | dir_ui->ui_size = dir->i_size; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 106bf20629ce..e6420677cebc 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -2039,6 +2039,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
2039 | if (c->max_inode_sz > MAX_LFS_FILESIZE) | 2039 | if (c->max_inode_sz > MAX_LFS_FILESIZE) |
2040 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; | 2040 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; |
2041 | sb->s_op = &ubifs_super_operations; | 2041 | sb->s_op = &ubifs_super_operations; |
2042 | sb->s_xattr = ubifs_xattr_handlers; | ||
2042 | 2043 | ||
2043 | mutex_lock(&c->umount_mutex); | 2044 | mutex_lock(&c->umount_mutex); |
2044 | err = mount_ubifs(c); | 2045 | err = mount_ubifs(c); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index c4fe900c67ab..bc04b9c69891 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mtd/ubi.h> | 36 | #include <linux/mtd/ubi.h> |
37 | #include <linux/pagemap.h> | 37 | #include <linux/pagemap.h> |
38 | #include <linux/backing-dev.h> | 38 | #include <linux/backing-dev.h> |
39 | #include <linux/security.h> | ||
39 | #include "ubifs-media.h" | 40 | #include "ubifs-media.h" |
40 | 41 | ||
41 | /* Version of this UBIFS implementation */ | 42 | /* Version of this UBIFS implementation */ |
@@ -1465,6 +1466,7 @@ extern spinlock_t ubifs_infos_lock; | |||
1465 | extern atomic_long_t ubifs_clean_zn_cnt; | 1466 | extern atomic_long_t ubifs_clean_zn_cnt; |
1466 | extern struct kmem_cache *ubifs_inode_slab; | 1467 | extern struct kmem_cache *ubifs_inode_slab; |
1467 | extern const struct super_operations ubifs_super_operations; | 1468 | extern const struct super_operations ubifs_super_operations; |
1469 | extern const struct xattr_handler *ubifs_xattr_handlers[]; | ||
1468 | extern const struct address_space_operations ubifs_file_address_operations; | 1470 | extern const struct address_space_operations ubifs_file_address_operations; |
1469 | extern const struct file_operations ubifs_file_operations; | 1471 | extern const struct file_operations ubifs_file_operations; |
1470 | extern const struct inode_operations ubifs_file_inode_operations; | 1472 | extern const struct inode_operations ubifs_file_inode_operations; |
@@ -1754,6 +1756,8 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, | |||
1754 | size_t size); | 1756 | size_t size); |
1755 | ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); | 1757 | ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); |
1756 | int ubifs_removexattr(struct dentry *dentry, const char *name); | 1758 | int ubifs_removexattr(struct dentry *dentry, const char *name); |
1759 | int ubifs_init_security(struct inode *dentry, struct inode *inode, | ||
1760 | const struct qstr *qstr); | ||
1757 | 1761 | ||
1758 | /* super.c */ | 1762 | /* super.c */ |
1759 | struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); | 1763 | struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index c3254a681a78..2bdab8b11f3f 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -575,3 +575,81 @@ out_free: | |||
575 | kfree(xent); | 575 | kfree(xent); |
576 | return err; | 576 | return err; |
577 | } | 577 | } |
578 | |||
579 | static size_t security_listxattr(struct dentry *d, char *list, size_t list_size, | ||
580 | const char *name, size_t name_len, int flags) | ||
581 | { | ||
582 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
583 | const size_t total_len = prefix_len + name_len + 1; | ||
584 | |||
585 | if (list && total_len <= list_size) { | ||
586 | memcpy(list, XATTR_SECURITY_PREFIX, prefix_len); | ||
587 | memcpy(list + prefix_len, name, name_len); | ||
588 | list[prefix_len + name_len] = '\0'; | ||
589 | } | ||
590 | |||
591 | return total_len; | ||
592 | } | ||
593 | |||
594 | static int security_getxattr(struct dentry *d, const char *name, void *buffer, | ||
595 | size_t size, int flags) | ||
596 | { | ||
597 | return ubifs_getxattr(d, name, buffer, size); | ||
598 | } | ||
599 | |||
600 | static int security_setxattr(struct dentry *d, const char *name, | ||
601 | const void *value, size_t size, int flags, | ||
602 | int handler_flags) | ||
603 | { | ||
604 | return ubifs_setxattr(d, name, value, size, flags); | ||
605 | } | ||
606 | |||
607 | static const struct xattr_handler ubifs_xattr_security_handler = { | ||
608 | .prefix = XATTR_SECURITY_PREFIX, | ||
609 | .list = security_listxattr, | ||
610 | .get = security_getxattr, | ||
611 | .set = security_setxattr, | ||
612 | }; | ||
613 | |||
614 | const struct xattr_handler *ubifs_xattr_handlers[] = { | ||
615 | &ubifs_xattr_security_handler, | ||
616 | NULL, | ||
617 | }; | ||
618 | |||
619 | static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, | ||
620 | void *fs_info) | ||
621 | { | ||
622 | const struct xattr *xattr; | ||
623 | char *name; | ||
624 | int err = 0; | ||
625 | |||
626 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { | ||
627 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + | ||
628 | strlen(xattr->name) + 1, GFP_NOFS); | ||
629 | if (!name) { | ||
630 | err = -ENOMEM; | ||
631 | break; | ||
632 | } | ||
633 | strcpy(name, XATTR_SECURITY_PREFIX); | ||
634 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); | ||
635 | err = setxattr(inode, name, xattr->value, xattr->value_len, 0); | ||
636 | kfree(name); | ||
637 | if (err < 0) | ||
638 | break; | ||
639 | } | ||
640 | |||
641 | return err; | ||
642 | } | ||
643 | |||
644 | int ubifs_init_security(struct inode *dentry, struct inode *inode, | ||
645 | const struct qstr *qstr) | ||
646 | { | ||
647 | int err; | ||
648 | |||
649 | mutex_lock(&inode->i_mutex); | ||
650 | err = security_inode_init_security(inode, dentry, qstr, | ||
651 | &init_xattrs, 0); | ||
652 | mutex_unlock(&inode->i_mutex); | ||
653 | |||
654 | return err; | ||
655 | } | ||