summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnzo Matsumiya <ematsumiya@suse.de>2024-07-31 20:08:39 -0300
committerEnzo Matsumiya <ematsumiya@suse.de>2024-07-31 20:08:39 -0300
commitc17125968fc2d05d93c6b64c7ec003b372910043 (patch)
tree2f4a31f58a7f117620e95bb85ad00c979088360e
parent40a2fd6fc1dff7786b70a397e96c094407f1ea1a (diff)
downloadlinux-xattr.tar.gz
linux-xattr.tar.bz2
linux-xattr.zip
smb: client: fix xattrxattr
WIP Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
-rw-r--r--fs/smb/client/fs_context.c7
-rw-r--r--fs/smb/client/xattr.c54
2 files changed, 55 insertions, 6 deletions
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 20dc31a07a56..82fba942bbcd 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1022,10 +1022,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
}
break;
case Opt_user_xattr:
- if (result.negated)
- ctx->no_xattr = 1;
- else
- ctx->no_xattr = 0;
+ ctx->no_xattr = result.negated;
+ if (!ctx->no_xattr)
+ pr_warn_once("CIFS: Extended Attributes names are limited to 127 characters\n");
break;
case Opt_forceuid:
if (result.negated)
diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c
index 6780aa3e98a1..6242c3643b39 100644
--- a/fs/smb/client/xattr.c
+++ b/fs/smb/client/xattr.c
@@ -88,6 +88,42 @@ static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon,
return rc;
}
+static char *xattr_encode_name(const char *name)
+{
+ const char forbidden[] = "\\/:*?\"<>|,+=[];";
+ char *new, *p;
+ size_t len = strlen(name);
+ int i, j;
+
+ if (len > 127)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < sizeof(forbidden); i++)
+ for (j = 0; j < len; j++)
+ if (name[j] == forbidden[i])
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < 0x20; i++)
+ for (j = 0; j < len; j++)
+ if (name[j] == i)
+ return ERR_PTR(-EINVAL);
+
+ new = kzalloc(len * 2 + 1, GFP_KERNEL);
+ if (!new)
+ return ERR_PTR(-ENOMEM);
+
+ p = new;
+ for (i = 0; i < len; i++)
+ p += snprintf(p, 3, "%02X", name[i]);
+
+ return new;
+}
+
+static char *xattr_decode_name(const char *name)
+{
+ num_to_str(&name[i]...);
+}
+
static int cifs_xattr_set(const struct xattr_handler *handler,
struct mnt_idmap *idmap,
struct dentry *dentry, struct inode *inode,
@@ -101,8 +137,14 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
const char *full_path;
+ char *new_name;
void *page;
+ pr_err("%s: name %s\n", __func__, name);
+ pr_err("%s: size %zu\n", __func__, size);
+ if (value)
+ print_hex_dump(KERN_ERR, "VALUE: ", DUMP_PREFIX_NONE, 16, 1, value, size, false);
+
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
@@ -116,8 +158,16 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
rc = PTR_ERR(full_path);
goto out;
}
- /* return dos attributes as pseudo xattr */
- /* return alt name if available as pseudo attr */
+
+ new_name = xattr_encode_name(name);
+ if (IS_ERR(new_name)) {
+ rc = PTR_ERR(new_name);
+ pr_err("%s: err %d\n", __func__, rc);
+ goto out;
+ }
+
+ pr_err("%s: old name %s, new name %s\n", __func__, name, new_name);
+ kfree(new_name);
/* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to