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)]))
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)
{
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);
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);
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);