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 13 static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, 14 void *buffer, size_t size, int type) 15 { 16 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 17 size_t len = strlen(name); 18 19 if (!strcmp(name, "")) 20 return -EINVAL; 21 22 if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN) 23 return -EOPNOTSUPP; 24 25 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 26 strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); 27 28 return hfsplus_getxattr(dentry, xattr_name, buffer, size); 29 } 30 31 static int hfsplus_security_setxattr(struct dentry *dentry, const char *name, 32 const void *buffer, size_t size, int flags, int type) 33 { 34 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 35 size_t len = strlen(name); 36 37 if (!strcmp(name, "")) 38 return -EINVAL; 39 40 if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN) 41 return -EOPNOTSUPP; 42 43 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 44 strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); 45 46 return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); 47 } 48 49 static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list, 50 size_t list_size, const char *name, size_t name_len, int type) 51 { 52 /* 53 * This method is not used. 54 * It is used hfsplus_listxattr() instead of generic_listxattr(). 55 */ 56 return -EOPNOTSUPP; 57 } 58 59 static int hfsplus_initxattrs(struct inode *inode, 60 const struct xattr *xattr_array, 61 void *fs_info) 62 { 63 const struct xattr *xattr; 64 char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0}; 65 size_t xattr_name_len; 66 int err = 0; 67 68 for (xattr = xattr_array; xattr->name != NULL; xattr++) { 69 xattr_name_len = strlen(xattr->name); 70 71 if (xattr_name_len == 0) 72 continue; 73 74 if (xattr_name_len + XATTR_SECURITY_PREFIX_LEN > 75 HFSPLUS_ATTR_MAX_STRLEN) 76 return -EOPNOTSUPP; 77 78 strcpy(xattr_name, XATTR_SECURITY_PREFIX); 79 strcpy(xattr_name + 80 XATTR_SECURITY_PREFIX_LEN, xattr->name); 81 memset(xattr_name + 82 XATTR_SECURITY_PREFIX_LEN + xattr_name_len, 0, 1); 83 84 err = __hfsplus_setxattr(inode, xattr_name, 85 xattr->value, xattr->value_len, 0); 86 if (err) 87 break; 88 } 89 return err; 90 } 91 92 int hfsplus_init_security(struct inode *inode, struct inode *dir, 93 const struct qstr *qstr) 94 { 95 return security_inode_init_security(inode, dir, qstr, 96 &hfsplus_initxattrs, NULL); 97 } 98 99 const struct xattr_handler hfsplus_xattr_security_handler = { 100 .prefix = XATTR_SECURITY_PREFIX, 101 .list = hfsplus_security_listxattr, 102 .get = hfsplus_security_getxattr, 103 .set = hfsplus_security_setxattr, 104 }; 105