jfs: don't allow os2 xattr namespace overlap with others

It's currently possible to bypass xattr namespace access rules by
prefixing valid xattr names with "os2.", since the os2 namespace stores
extended attributes in a legacy format with no prefix.

This patch adds checking to deny access to any valid namespace prefix
following "os2.".

Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Reported-by: Sergey Vlasov <vsu@altlinux.ru>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dave Kleikamp and committed by
Linus Torvalds
aca0fa34 2f9e825d

+38 -49
+38 -49
fs/jfs/xattr.c
··· 86 86 #define EA_MALLOC 0x0008 87 87 88 88 89 + static int is_known_namespace(const char *name) 90 + { 91 + if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && 92 + strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && 93 + strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && 94 + strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) 95 + return false; 96 + 97 + return true; 98 + } 99 + 89 100 /* 90 101 * These three routines are used to recognize on-disk extended attributes 91 102 * that are in a recognized namespace. If the attribute is not recognized, 92 103 * "os2." is prepended to the name 93 104 */ 94 - static inline int is_os2_xattr(struct jfs_ea *ea) 105 + static int is_os2_xattr(struct jfs_ea *ea) 95 106 { 96 - /* 97 - * Check for "system." 98 - */ 99 - if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) && 100 - !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 101 - return false; 102 - /* 103 - * Check for "user." 104 - */ 105 - if ((ea->namelen >= XATTR_USER_PREFIX_LEN) && 106 - !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) 107 - return false; 108 - /* 109 - * Check for "security." 110 - */ 111 - if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) && 112 - !strncmp(ea->name, XATTR_SECURITY_PREFIX, 113 - XATTR_SECURITY_PREFIX_LEN)) 114 - return false; 115 - /* 116 - * Check for "trusted." 117 - */ 118 - if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) && 119 - !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) 120 - return false; 121 - /* 122 - * Add any other valid namespace prefixes here 123 - */ 124 - 125 - /* 126 - * We assume it's OS/2's flat namespace 127 - */ 128 - return true; 107 + return !is_known_namespace(ea->name); 129 108 } 130 109 131 110 static inline int name_size(struct jfs_ea *ea) ··· 743 764 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 744 765 return can_set_system_xattr(inode, name, value, value_len); 745 766 767 + if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { 768 + /* 769 + * This makes sure that we aren't trying to set an 770 + * attribute in a different namespace by prefixing it 771 + * with "os2." 772 + */ 773 + if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) 774 + return -EOPNOTSUPP; 775 + return 0; 776 + } 777 + 746 778 /* 747 779 * Don't allow setting an attribute in an unknown namespace. 748 780 */ 749 781 if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) && 750 782 strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && 751 - strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && 752 - strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) 783 + strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) 753 784 return -EOPNOTSUPP; 754 785 755 786 return 0; ··· 941 952 int xattr_size; 942 953 ssize_t size; 943 954 int namelen = strlen(name); 944 - char *os2name = NULL; 945 955 char *value; 946 - 947 - if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { 948 - os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, 949 - GFP_KERNEL); 950 - if (!os2name) 951 - return -ENOMEM; 952 - strcpy(os2name, name + XATTR_OS2_PREFIX_LEN); 953 - name = os2name; 954 - namelen -= XATTR_OS2_PREFIX_LEN; 955 - } 956 956 957 957 down_read(&JFS_IP(inode)->xattr_sem); 958 958 ··· 980 1002 out: 981 1003 up_read(&JFS_IP(inode)->xattr_sem); 982 1004 983 - kfree(os2name); 984 - 985 1005 return size; 986 1006 } 987 1007 ··· 987 1011 size_t buf_size) 988 1012 { 989 1013 int err; 1014 + 1015 + if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { 1016 + /* 1017 + * skip past "os2." prefix 1018 + */ 1019 + name += XATTR_OS2_PREFIX_LEN; 1020 + /* 1021 + * Don't allow retrieving properly prefixed attributes 1022 + * by prepending them with "os2." 1023 + */ 1024 + if (is_known_namespace(name)) 1025 + return -EOPNOTSUPP; 1026 + } 990 1027 991 1028 err = __jfs_getxattr(dentry->d_inode, name, data, buf_size); 992 1029