Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[platform/adaptation/renesas_rcar/renesas_kernel.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 "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 };