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