diff options
Diffstat (limited to 'fs/ubifs/xattr.c')
-rw-r--r-- | fs/ubifs/xattr.c | 78 |
1 files changed, 78 insertions, 0 deletions
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 | } | ||