aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSubodh Nijsure <snijsure@grid-net.com>2014-10-31 14:50:30 -0400
committerRichard Weinberger <richard@nod.at>2015-01-28 10:08:54 -0500
commitd7f0b70d30ffb9bbe6b8a3e1035cf0b79965ef53 (patch)
treea903ee476aad8a9dcff9ef5cd9d4a4626e679990
parent895d9db253a0b0b1f8a6e635fb2460d80bf72d5a (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>
-rw-r--r--fs/ubifs/dir.c16
-rw-r--r--fs/ubifs/super.c1
-rw-r--r--fs/ubifs/ubifs.h4
-rw-r--r--fs/ubifs/xattr.c78
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;
1465extern atomic_long_t ubifs_clean_zn_cnt; 1466extern atomic_long_t ubifs_clean_zn_cnt;
1466extern struct kmem_cache *ubifs_inode_slab; 1467extern struct kmem_cache *ubifs_inode_slab;
1467extern const struct super_operations ubifs_super_operations; 1468extern const struct super_operations ubifs_super_operations;
1469extern const struct xattr_handler *ubifs_xattr_handlers[];
1468extern const struct address_space_operations ubifs_file_address_operations; 1470extern const struct address_space_operations ubifs_file_address_operations;
1469extern const struct file_operations ubifs_file_operations; 1471extern const struct file_operations ubifs_file_operations;
1470extern const struct inode_operations ubifs_file_inode_operations; 1472extern 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);
1755ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); 1757ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
1756int ubifs_removexattr(struct dentry *dentry, const char *name); 1758int ubifs_removexattr(struct dentry *dentry, const char *name);
1759int ubifs_init_security(struct inode *dentry, struct inode *inode,
1760 const struct qstr *qstr);
1757 1761
1758/* super.c */ 1762/* super.c */
1759struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); 1763struct 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
579static 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
594static 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
600static 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
607static 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
614const struct xattr_handler *ubifs_xattr_handlers[] = {
615 &ubifs_xattr_security_handler,
616 NULL,
617};
618
619static 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
644int 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}