Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / fs / hfsplus / xattr_security.c
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         char *xattr_name;
20         int res;
21
22         if (!strcmp(name, ""))
23                 return -EINVAL;
24
25         xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1,
26                 GFP_KERNEL);
27         if (!xattr_name)
28                 return -ENOMEM;
29         strcpy(xattr_name, XATTR_SECURITY_PREFIX);
30         strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name);
31
32         res = hfsplus_getxattr(dentry, xattr_name, buffer, size);
33         kfree(xattr_name);
34         return res;
35 }
36
37 static int hfsplus_security_setxattr(struct dentry *dentry, const char *name,
38                 const void *buffer, size_t size, int flags, int type)
39 {
40         char *xattr_name;
41         int res;
42
43         if (!strcmp(name, ""))
44                 return -EINVAL;
45
46         xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1,
47                 GFP_KERNEL);
48         if (!xattr_name)
49                 return -ENOMEM;
50         strcpy(xattr_name, XATTR_SECURITY_PREFIX);
51         strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name);
52
53         res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags);
54         kfree(xattr_name);
55         return res;
56 }
57
58 static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list,
59                 size_t list_size, const char *name, size_t name_len, int type)
60 {
61         /*
62          * This method is not used.
63          * It is used hfsplus_listxattr() instead of generic_listxattr().
64          */
65         return -EOPNOTSUPP;
66 }
67
68 static int hfsplus_initxattrs(struct inode *inode,
69                                 const struct xattr *xattr_array,
70                                 void *fs_info)
71 {
72         const struct xattr *xattr;
73         char *xattr_name;
74         int err = 0;
75
76         xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1,
77                 GFP_KERNEL);
78         if (!xattr_name)
79                 return -ENOMEM;
80         for (xattr = xattr_array; xattr->name != NULL; xattr++) {
81
82                 if (!strcmp(xattr->name, ""))
83                         continue;
84
85                 strcpy(xattr_name, XATTR_SECURITY_PREFIX);
86                 strcpy(xattr_name +
87                         XATTR_SECURITY_PREFIX_LEN, xattr->name);
88                 memset(xattr_name +
89                         XATTR_SECURITY_PREFIX_LEN + strlen(xattr->name), 0, 1);
90
91                 err = __hfsplus_setxattr(inode, xattr_name,
92                                         xattr->value, xattr->value_len, 0);
93                 if (err)
94                         break;
95         }
96         kfree(xattr_name);
97         return err;
98 }
99
100 int hfsplus_init_security(struct inode *inode, struct inode *dir,
101                                 const struct qstr *qstr)
102 {
103         return security_inode_init_security(inode, dir, qstr,
104                                         &hfsplus_initxattrs, NULL);
105 }
106
107 int hfsplus_init_inode_security(struct inode *inode,
108                                                 struct inode *dir,
109                                                 const struct qstr *qstr)
110 {
111         int err;
112
113         err = hfsplus_init_posix_acl(inode, dir);
114         if (!err)
115                 err = hfsplus_init_security(inode, dir, qstr);
116         return err;
117 }
118
119 const struct xattr_handler hfsplus_xattr_security_handler = {
120         .prefix = XATTR_SECURITY_PREFIX,
121         .list   = hfsplus_security_listxattr,
122         .get    = hfsplus_security_getxattr,
123         .set    = hfsplus_security_setxattr,
124 };