aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/xattr.c')
-rw-r--r--fs/hfsplus/xattr.c92
1 files changed, 6 insertions, 86 deletions
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 3c6136f98c73..0b4a5c9b93c4 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include "hfsplus_fs.h" 9#include "hfsplus_fs.h"
10#include <linux/posix_acl_xattr.h>
10#include "xattr.h" 11#include "xattr.h"
11#include "acl.h" 12#include "acl.h"
12 13
@@ -15,8 +16,8 @@ const struct xattr_handler *hfsplus_xattr_handlers[] = {
15 &hfsplus_xattr_user_handler, 16 &hfsplus_xattr_user_handler,
16 &hfsplus_xattr_trusted_handler, 17 &hfsplus_xattr_trusted_handler,
17#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 18#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
18 &hfsplus_xattr_acl_access_handler, 19 &posix_acl_access_xattr_handler,
19 &hfsplus_xattr_acl_default_handler, 20 &posix_acl_default_xattr_handler,
20#endif 21#endif
21 &hfsplus_xattr_security_handler, 22 &hfsplus_xattr_security_handler,
22 NULL 23 NULL
@@ -51,82 +52,6 @@ static inline int is_known_namespace(const char *name)
51 return true; 52 return true;
52} 53}
53 54
54static int can_set_system_xattr(struct inode *inode, const char *name,
55 const void *value, size_t size)
56{
57#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
58 struct posix_acl *acl;
59 int err;
60
61 if (!inode_owner_or_capable(inode))
62 return -EPERM;
63
64 /*
65 * POSIX_ACL_XATTR_ACCESS is tied to i_mode
66 */
67 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
68 acl = posix_acl_from_xattr(&init_user_ns, value, size);
69 if (IS_ERR(acl))
70 return PTR_ERR(acl);
71 if (acl) {
72 err = posix_acl_equiv_mode(acl, &inode->i_mode);
73 posix_acl_release(acl);
74 if (err < 0)
75 return err;
76 mark_inode_dirty(inode);
77 }
78 /*
79 * We're changing the ACL. Get rid of the cached one
80 */
81 forget_cached_acl(inode, ACL_TYPE_ACCESS);
82
83 return 0;
84 } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
85 acl = posix_acl_from_xattr(&init_user_ns, value, size);
86 if (IS_ERR(acl))
87 return PTR_ERR(acl);
88 posix_acl_release(acl);
89
90 /*
91 * We're changing the default ACL. Get rid of the cached one
92 */
93 forget_cached_acl(inode, ACL_TYPE_DEFAULT);
94
95 return 0;
96 }
97#endif /* CONFIG_HFSPLUS_FS_POSIX_ACL */
98 return -EOPNOTSUPP;
99}
100
101static int can_set_xattr(struct inode *inode, const char *name,
102 const void *value, size_t value_len)
103{
104 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
105 return can_set_system_xattr(inode, name, value, value_len);
106
107 if (!strncmp(name, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN)) {
108 /*
109 * This makes sure that we aren't trying to set an
110 * attribute in a different namespace by prefixing it
111 * with "osx."
112 */
113 if (is_known_namespace(name + XATTR_MAC_OSX_PREFIX_LEN))
114 return -EOPNOTSUPP;
115
116 return 0;
117 }
118
119 /*
120 * Don't allow setting an attribute in an unknown namespace.
121 */
122 if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
123 strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
124 strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
125 return -EOPNOTSUPP;
126
127 return 0;
128}
129
130static void hfsplus_init_header_node(struct inode *attr_file, 55static void hfsplus_init_header_node(struct inode *attr_file,
131 u32 clump_size, 56 u32 clump_size,
132 char *buf, u16 node_size) 57 char *buf, u16 node_size)
@@ -349,10 +274,6 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
349 HFSPLUS_IS_RSRC(inode)) 274 HFSPLUS_IS_RSRC(inode))
350 return -EOPNOTSUPP; 275 return -EOPNOTSUPP;
351 276
352 err = can_set_xattr(inode, name, value, size);
353 if (err)
354 return err;
355
356 if (strncmp(name, XATTR_MAC_OSX_PREFIX, 277 if (strncmp(name, XATTR_MAC_OSX_PREFIX,
357 XATTR_MAC_OSX_PREFIX_LEN) == 0) 278 XATTR_MAC_OSX_PREFIX_LEN) == 0)
358 name += XATTR_MAC_OSX_PREFIX_LEN; 279 name += XATTR_MAC_OSX_PREFIX_LEN;
@@ -840,10 +761,6 @@ int hfsplus_removexattr(struct dentry *dentry, const char *name)
840 if (!HFSPLUS_SB(inode->i_sb)->attr_tree) 761 if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
841 return -EOPNOTSUPP; 762 return -EOPNOTSUPP;
842 763
843 err = can_set_xattr(inode, name, NULL, 0);
844 if (err)
845 return err;
846
847 if (strncmp(name, XATTR_MAC_OSX_PREFIX, 764 if (strncmp(name, XATTR_MAC_OSX_PREFIX,
848 XATTR_MAC_OSX_PREFIX_LEN) == 0) 765 XATTR_MAC_OSX_PREFIX_LEN) == 0)
849 name += XATTR_MAC_OSX_PREFIX_LEN; 766 name += XATTR_MAC_OSX_PREFIX_LEN;
@@ -940,6 +857,9 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
940 if (len > HFSPLUS_ATTR_MAX_STRLEN) 857 if (len > HFSPLUS_ATTR_MAX_STRLEN)
941 return -EOPNOTSUPP; 858 return -EOPNOTSUPP;
942 859
860 if (is_known_namespace(name))
861 return -EOPNOTSUPP;
862
943 strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); 863 strcpy(xattr_name, XATTR_MAC_OSX_PREFIX);
944 strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); 864 strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name);
945 865