xref: /openbmc/linux/fs/hfsplus/xattr_security.c (revision e23feb16)
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 
14 static 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 
32 static 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 
50 static 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 
60 static 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 
93 int 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 
100 int 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 
112 const 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 };
118