From: Darrick J. Wong <djwong@xxxxxxxxxx> Ignore any xattr calls for name prefixes that the kernel doesn't also support. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- lib/ext2fs/ext2fsP.h | 3 +++ misc/fuse2fs.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h index d1f2105e9813ca..428081c9e2ff38 100644 --- a/lib/ext2fs/ext2fsP.h +++ b/lib/ext2fs/ext2fsP.h @@ -214,4 +214,7 @@ typedef void (*ext2_exit_fn)(void *); errcode_t ext2fs_add_exit_fn(ext2_exit_fn fn, void *data); errcode_t ext2fs_remove_exit_fn(ext2_exit_fn fn, void *data); +#define ARRAY_SIZE(array) \ + (sizeof(array) / sizeof(array[0])) + #define EXT2FS_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2*!!(cond)])) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 74bbe661a417e5..28b77d367cf705 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -2443,6 +2443,27 @@ static int op_statfs(const char *path EXT2FS_ATTR((unused)), return 0; } +static const char *valid_xattr_prefixes[] = { + "user.", + "trusted.", + "security.", + "gnu.", + "system.", +}; + +static int validate_xattr_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(valid_xattr_prefixes); i++) { + if (!strncmp(name, valid_xattr_prefixes[i], + strlen(valid_xattr_prefixes[i]))) + return 1; + } + + return 0; +} + static int op_getxattr(const char *path, const char *key, char *value, size_t len) { @@ -2456,6 +2477,9 @@ static int op_getxattr(const char *path, const char *key, char *value, errcode_t err; int ret = 0; + if (!validate_xattr_name(key)) + return -ENODATA; + FUSE2FS_CHECK_CONTEXT(ff); fs = ff->fs; pthread_mutex_lock(&ff->bfl); @@ -2626,6 +2650,9 @@ static int op_setxattr(const char *path EXT2FS_ATTR((unused)), if (flags & ~(XATTR_CREATE | XATTR_REPLACE)) return -EOPNOTSUPP; + if (!validate_xattr_name(key)) + return -EINVAL; + FUSE2FS_CHECK_CONTEXT(ff); fs = ff->fs; pthread_mutex_lock(&ff->bfl); @@ -2714,6 +2741,16 @@ static int op_removexattr(const char *path, const char *key) errcode_t err; int ret = 0; + /* + * Once in a while libfuse gives us a no-name xattr to delete as part + * of clearing ACLs. Just pretend we cleared them. + */ + if (key[0] == 0) + return 0; + + if (!validate_xattr_name(key)) + return -ENODATA; + FUSE2FS_CHECK_CONTEXT(ff); fs = ff->fs; pthread_mutex_lock(&ff->bfl);