Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.12-rc2 117 lines 3.0 kB view raw
1/* 2 * linux/fs/hfsplus/xattr_trusted.c 3 * 4 * Vyacheslav Dubeyko <slava@dubeyko.com> 5 * 6 * Handler for storing security labels as extended attributes. 7 */ 8 9#include <linux/security.h> 10#include "hfsplus_fs.h" 11#include "xattr.h" 12#include "acl.h" 13 14static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, 15 void *buffer, size_t size, int type) 16{ 17 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 18 size_t len = strlen(name); 19 20 if (!strcmp(name, "")) 21 return -EINVAL; 22 23 if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN) 24 return -EOPNOTSUPP; 25 26 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 27 strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); 28 29 return hfsplus_getxattr(dentry, xattr_name, buffer, size); 30} 31 32static int hfsplus_security_setxattr(struct dentry *dentry, const char *name, 33 const void *buffer, size_t size, int flags, int type) 34{ 35 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 36 size_t len = strlen(name); 37 38 if (!strcmp(name, "")) 39 return -EINVAL; 40 41 if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN) 42 return -EOPNOTSUPP; 43 44 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 45 strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); 46 47 return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); 48} 49 50static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list, 51 size_t list_size, const char *name, size_t name_len, int type) 52{ 53 /* 54 * This method is not used. 55 * It is used hfsplus_listxattr() instead of generic_listxattr(). 56 */ 57 return -EOPNOTSUPP; 58} 59 60static int hfsplus_initxattrs(struct inode *inode, 61 const struct xattr *xattr_array, 62 void *fs_info) 63{ 64 const struct xattr *xattr; 65 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 66 size_t xattr_name_len; 67 int err = 0; 68 69 for (xattr = xattr_array; xattr->name != NULL; xattr++) { 70 xattr_name_len = strlen(xattr->name); 71 72 if (xattr_name_len == 0) 73 continue; 74 75 if (xattr_name_len + XATTR_SECURITY_PREFIX_LEN > 76 HFSPLUS_ATTR_MAX_STRLEN) 77 return -EOPNOTSUPP; 78 79 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 80 strcpy(xattr_name + 81 XATTR_SECURITY_PREFIX_LEN, xattr->name); 82 memset(xattr_name + 83 XATTR_SECURITY_PREFIX_LEN + xattr_name_len, 0, 1); 84 85 err = __hfsplus_setxattr(inode, xattr_name, 86 xattr->value, xattr->value_len, 0); 87 if (err) 88 break; 89 } 90 return err; 91} 92 93int hfsplus_init_security(struct inode *inode, struct inode *dir, 94 const struct qstr *qstr) 95{ 96 return security_inode_init_security(inode, dir, qstr, 97 &hfsplus_initxattrs, NULL); 98} 99 100int hfsplus_init_inode_security(struct inode *inode, 101 struct inode *dir, 102 const struct qstr *qstr) 103{ 104 int err; 105 106 err = hfsplus_init_posix_acl(inode, dir); 107 if (!err) 108 err = hfsplus_init_security(inode, dir, qstr); 109 return err; 110} 111 112const struct xattr_handler hfsplus_xattr_security_handler = { 113 .prefix = XATTR_SECURITY_PREFIX, 114 .list = hfsplus_security_listxattr, 115 .get = hfsplus_security_getxattr, 116 .set = hfsplus_security_setxattr, 117};