• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
hfsplus_security_getxattr(struct dentry * dentry,const char * name,void * buffer,size_t size,int type)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 
hfsplus_security_setxattr(struct dentry * dentry,const char * name,const void * buffer,size_t size,int flags,int type)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 
hfsplus_security_listxattr(struct dentry * dentry,char * list,size_t list_size,const char * name,size_t name_len,int type)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 
hfsplus_initxattrs(struct inode * inode,const struct xattr * xattr_array,void * fs_info)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 
hfsplus_init_security(struct inode * inode,struct inode * dir,const struct qstr * qstr)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