|
@@ -86,46 +86,25 @@ struct ea_buffer {
|
|
#define EA_MALLOC 0x0008
|
|
#define EA_MALLOC 0x0008
|
|
|
|
|
|
|
|
|
|
|
|
+static int is_known_namespace(const char *name)
|
|
|
|
+{
|
|
|
|
+ if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) &&
|
|
|
|
+ strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
|
|
|
|
+ strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
|
|
|
|
+ strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* These three routines are used to recognize on-disk extended attributes
|
|
* These three routines are used to recognize on-disk extended attributes
|
|
* that are in a recognized namespace. If the attribute is not recognized,
|
|
* that are in a recognized namespace. If the attribute is not recognized,
|
|
* "os2." is prepended to the name
|
|
* "os2." is prepended to the name
|
|
*/
|
|
*/
|
|
-static inline int is_os2_xattr(struct jfs_ea *ea)
|
|
|
|
|
|
+static int is_os2_xattr(struct jfs_ea *ea)
|
|
{
|
|
{
|
|
- /*
|
|
|
|
- * Check for "system."
|
|
|
|
- */
|
|
|
|
- if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) &&
|
|
|
|
- !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
|
|
|
|
- return false;
|
|
|
|
- /*
|
|
|
|
- * Check for "user."
|
|
|
|
- */
|
|
|
|
- if ((ea->namelen >= XATTR_USER_PREFIX_LEN) &&
|
|
|
|
- !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
|
|
|
|
- return false;
|
|
|
|
- /*
|
|
|
|
- * Check for "security."
|
|
|
|
- */
|
|
|
|
- if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) &&
|
|
|
|
- !strncmp(ea->name, XATTR_SECURITY_PREFIX,
|
|
|
|
- XATTR_SECURITY_PREFIX_LEN))
|
|
|
|
- return false;
|
|
|
|
- /*
|
|
|
|
- * Check for "trusted."
|
|
|
|
- */
|
|
|
|
- if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) &&
|
|
|
|
- !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
|
|
|
|
- return false;
|
|
|
|
- /*
|
|
|
|
- * Add any other valid namespace prefixes here
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * We assume it's OS/2's flat namespace
|
|
|
|
- */
|
|
|
|
- return true;
|
|
|
|
|
|
+ return !is_known_namespace(ea->name);
|
|
}
|
|
}
|
|
|
|
|
|
static inline int name_size(struct jfs_ea *ea)
|
|
static inline int name_size(struct jfs_ea *ea)
|
|
@@ -764,13 +743,23 @@ static int can_set_xattr(struct inode *inode, const char *name,
|
|
if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
|
|
if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
|
|
return can_set_system_xattr(inode, name, value, value_len);
|
|
return can_set_system_xattr(inode, name, value, value_len);
|
|
|
|
|
|
|
|
+ if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) {
|
|
|
|
+ /*
|
|
|
|
+ * This makes sure that we aren't trying to set an
|
|
|
|
+ * attribute in a different namespace by prefixing it
|
|
|
|
+ * with "os2."
|
|
|
|
+ */
|
|
|
|
+ if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Don't allow setting an attribute in an unknown namespace.
|
|
* Don't allow setting an attribute in an unknown namespace.
|
|
*/
|
|
*/
|
|
if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
|
|
if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
|
|
strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
|
|
strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
|
|
- strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
|
|
|
|
- strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))
|
|
|
|
|
|
+ strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -952,19 +941,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
|
|
int xattr_size;
|
|
int xattr_size;
|
|
ssize_t size;
|
|
ssize_t size;
|
|
int namelen = strlen(name);
|
|
int namelen = strlen(name);
|
|
- char *os2name = NULL;
|
|
|
|
char *value;
|
|
char *value;
|
|
|
|
|
|
- if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
|
|
|
|
- os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
|
|
|
|
- GFP_KERNEL);
|
|
|
|
- if (!os2name)
|
|
|
|
- return -ENOMEM;
|
|
|
|
- strcpy(os2name, name + XATTR_OS2_PREFIX_LEN);
|
|
|
|
- name = os2name;
|
|
|
|
- namelen -= XATTR_OS2_PREFIX_LEN;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
down_read(&JFS_IP(inode)->xattr_sem);
|
|
down_read(&JFS_IP(inode)->xattr_sem);
|
|
|
|
|
|
xattr_size = ea_get(inode, &ea_buf, 0);
|
|
xattr_size = ea_get(inode, &ea_buf, 0);
|
|
@@ -1002,8 +980,6 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
|
|
out:
|
|
out:
|
|
up_read(&JFS_IP(inode)->xattr_sem);
|
|
up_read(&JFS_IP(inode)->xattr_sem);
|
|
|
|
|
|
- kfree(os2name);
|
|
|
|
-
|
|
|
|
return size;
|
|
return size;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1012,6 +988,19 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
|
|
{
|
|
{
|
|
int err;
|
|
int err;
|
|
|
|
|
|
|
|
+ if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
|
|
|
|
+ /*
|
|
|
|
+ * skip past "os2." prefix
|
|
|
|
+ */
|
|
|
|
+ name += XATTR_OS2_PREFIX_LEN;
|
|
|
|
+ /*
|
|
|
|
+ * Don't allow retrieving properly prefixed attributes
|
|
|
|
+ * by prepending them with "os2."
|
|
|
|
+ */
|
|
|
|
+ if (is_known_namespace(name))
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+ }
|
|
|
|
+
|
|
err = __jfs_getxattr(dentry->d_inode, name, data, buf_size);
|
|
err = __jfs_getxattr(dentry->d_inode, name, data, buf_size);
|
|
|
|
|
|
return err;
|
|
return err;
|