diff options
Diffstat (limited to 'fs/hfsplus/xattr.c')
-rw-r--r-- | fs/hfsplus/xattr.c | 92 |
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 | ||
54 | static 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 | |||
101 | static 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 | |||
130 | static void hfsplus_init_header_node(struct inode *attr_file, | 55 | static 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 | ||