diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-04-22 08:43:48 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 22:29:18 -0400 |
commit | 6c8f980c75185f8ba897814363d21882f7453f53 (patch) | |
tree | efbb19e3dbfdf9d019d0726724fb8a216166586f | |
parent | 1a39ba99b5d533647c5dac45cd6a3e0baa7cb66a (diff) |
jfs: Clean up xattr name mapping
Instead of stripping "os2." prefixes in __jfs_setxattr, make callers
strip them, as __jfs_getxattr already does. With that change, use the
same name mapping function in jfs_{get,set,remove}xattr.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/jfs/xattr.c | 80 |
1 files changed, 25 insertions, 55 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 5becc6a3ff8c..9cdf7dc4d5cb 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -86,6 +86,14 @@ struct ea_buffer { | |||
86 | #define EA_MALLOC 0x0008 | 86 | #define EA_MALLOC 0x0008 |
87 | 87 | ||
88 | 88 | ||
89 | /* | ||
90 | * Mapping of on-disk attribute names: for on-disk attribute names with an | ||
91 | * unknown prefix (not "system.", "user.", "security.", or "trusted."), the | ||
92 | * prefix "os2." is prepended. On the way back to disk, "os2." prefixes are | ||
93 | * stripped and we make sure that the remaining name does not start with one | ||
94 | * of the know prefixes. | ||
95 | */ | ||
96 | |||
89 | static int is_known_namespace(const char *name) | 97 | static int is_known_namespace(const char *name) |
90 | { | 98 | { |
91 | if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && | 99 | if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && |
@@ -97,29 +105,19 @@ static int is_known_namespace(const char *name) | |||
97 | return true; | 105 | return true; |
98 | } | 106 | } |
99 | 107 | ||
100 | /* | ||
101 | * These three routines are used to recognize on-disk extended attributes | ||
102 | * that are in a recognized namespace. If the attribute is not recognized, | ||
103 | * "os2." is prepended to the name | ||
104 | */ | ||
105 | static int is_os2_xattr(struct jfs_ea *ea) | ||
106 | { | ||
107 | return !is_known_namespace(ea->name); | ||
108 | } | ||
109 | |||
110 | static inline int name_size(struct jfs_ea *ea) | 108 | static inline int name_size(struct jfs_ea *ea) |
111 | { | 109 | { |
112 | if (is_os2_xattr(ea)) | 110 | if (is_known_namespace(ea->name)) |
113 | return ea->namelen + XATTR_OS2_PREFIX_LEN; | ||
114 | else | ||
115 | return ea->namelen; | 111 | return ea->namelen; |
112 | else | ||
113 | return ea->namelen + XATTR_OS2_PREFIX_LEN; | ||
116 | } | 114 | } |
117 | 115 | ||
118 | static inline int copy_name(char *buffer, struct jfs_ea *ea) | 116 | static inline int copy_name(char *buffer, struct jfs_ea *ea) |
119 | { | 117 | { |
120 | int len = ea->namelen; | 118 | int len = ea->namelen; |
121 | 119 | ||
122 | if (is_os2_xattr(ea)) { | 120 | if (!is_known_namespace(ea->name)) { |
123 | memcpy(buffer, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN); | 121 | memcpy(buffer, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN); |
124 | buffer += XATTR_OS2_PREFIX_LEN; | 122 | buffer += XATTR_OS2_PREFIX_LEN; |
125 | len += XATTR_OS2_PREFIX_LEN; | 123 | len += XATTR_OS2_PREFIX_LEN; |
@@ -669,29 +667,24 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, | |||
669 | * Most of the permission checking is done by xattr_permission in the vfs. | 667 | * Most of the permission checking is done by xattr_permission in the vfs. |
670 | * We also need to verify that this is a namespace that we recognize. | 668 | * We also need to verify that this is a namespace that we recognize. |
671 | */ | 669 | */ |
672 | static int can_set_xattr(struct inode *inode, const char *name, | 670 | static bool map_name_to_disk(const char **name) |
673 | const void *value, size_t value_len) | ||
674 | { | 671 | { |
675 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { | 672 | if (!strncmp(*name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { |
676 | /* | 673 | /* |
677 | * This makes sure that we aren't trying to set an | 674 | * This makes sure that we aren't trying to set an |
678 | * attribute in a different namespace by prefixing it | 675 | * attribute in a different namespace by prefixing it |
679 | * with "os2." | 676 | * with "os2." |
680 | */ | 677 | */ |
681 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) | 678 | if (is_known_namespace(*name + XATTR_OS2_PREFIX_LEN)) |
682 | return -EOPNOTSUPP; | 679 | return false; |
683 | return 0; | 680 | *name += XATTR_OS2_PREFIX_LEN; |
681 | return true; | ||
684 | } | 682 | } |
685 | 683 | ||
686 | /* | 684 | /* |
687 | * Don't allow setting an attribute in an unknown namespace. | 685 | * Don't allow setting an attribute in an unknown namespace. |
688 | */ | 686 | */ |
689 | if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) && | 687 | return is_known_namespace(*name); |
690 | strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && | ||
691 | strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) | ||
692 | return -EOPNOTSUPP; | ||
693 | |||
694 | return 0; | ||
695 | } | 688 | } |
696 | 689 | ||
697 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | 690 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, |
@@ -704,21 +697,10 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | |||
704 | int xattr_size; | 697 | int xattr_size; |
705 | int new_size; | 698 | int new_size; |
706 | int namelen = strlen(name); | 699 | int namelen = strlen(name); |
707 | char *os2name = NULL; | ||
708 | int found = 0; | 700 | int found = 0; |
709 | int rc; | 701 | int rc; |
710 | int length; | 702 | int length; |
711 | 703 | ||
712 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | ||
713 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, | ||
714 | GFP_KERNEL); | ||
715 | if (!os2name) | ||
716 | return -ENOMEM; | ||
717 | strcpy(os2name, name + XATTR_OS2_PREFIX_LEN); | ||
718 | name = os2name; | ||
719 | namelen -= XATTR_OS2_PREFIX_LEN; | ||
720 | } | ||
721 | |||
722 | down_write(&JFS_IP(inode)->xattr_sem); | 704 | down_write(&JFS_IP(inode)->xattr_sem); |
723 | 705 | ||
724 | xattr_size = ea_get(inode, &ea_buf, 0); | 706 | xattr_size = ea_get(inode, &ea_buf, 0); |
@@ -841,8 +823,6 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | |||
841 | out: | 823 | out: |
842 | up_write(&JFS_IP(inode)->xattr_sem); | 824 | up_write(&JFS_IP(inode)->xattr_sem); |
843 | 825 | ||
844 | kfree(os2name); | ||
845 | |||
846 | return rc; | 826 | return rc; |
847 | } | 827 | } |
848 | 828 | ||
@@ -862,8 +842,8 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
862 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | 842 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) |
863 | return generic_setxattr(dentry, name, value, value_len, flags); | 843 | return generic_setxattr(dentry, name, value, value_len, flags); |
864 | 844 | ||
865 | if ((rc = can_set_xattr(inode, name, value, value_len))) | 845 | if (!map_name_to_disk(&name)) |
866 | return rc; | 846 | return -EOPNOTSUPP; |
867 | 847 | ||
868 | if (value == NULL) { /* empty EA, do not remove */ | 848 | if (value == NULL) { /* empty EA, do not remove */ |
869 | value = ""; | 849 | value = ""; |
@@ -946,18 +926,8 @@ ssize_t jfs_getxattr(struct dentry *dentry, struct inode *inode, | |||
946 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | 926 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) |
947 | return generic_getxattr(dentry, inode, name, data, buf_size); | 927 | return generic_getxattr(dentry, inode, name, data, buf_size); |
948 | 928 | ||
949 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | 929 | if (!map_name_to_disk(&name)) |
950 | /* | 930 | return -EOPNOTSUPP; |
951 | * skip past "os2." prefix | ||
952 | */ | ||
953 | name += XATTR_OS2_PREFIX_LEN; | ||
954 | /* | ||
955 | * Don't allow retrieving properly prefixed attributes | ||
956 | * by prepending them with "os2." | ||
957 | */ | ||
958 | if (is_known_namespace(name)) | ||
959 | return -EOPNOTSUPP; | ||
960 | } | ||
961 | 931 | ||
962 | err = __jfs_getxattr(inode, name, data, buf_size); | 932 | err = __jfs_getxattr(inode, name, data, buf_size); |
963 | 933 | ||
@@ -1042,8 +1012,8 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1042 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | 1012 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) |
1043 | return generic_removexattr(dentry, name); | 1013 | return generic_removexattr(dentry, name); |
1044 | 1014 | ||
1045 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | 1015 | if (!map_name_to_disk(&name)) |
1046 | return rc; | 1016 | return -EOPNOTSUPP; |
1047 | 1017 | ||
1048 | tid = txBegin(inode->i_sb, 0); | 1018 | tid = txBegin(inode->i_sb, 0); |
1049 | mutex_lock(&ji->commit_mutex); | 1019 | mutex_lock(&ji->commit_mutex); |