diff options
author | Enzo Matsumiya <ematsumiya@suse.de> | 2024-07-31 20:08:39 -0300 |
---|---|---|
committer | Enzo Matsumiya <ematsumiya@suse.de> | 2024-07-31 20:08:39 -0300 |
commit | c17125968fc2d05d93c6b64c7ec003b372910043 (patch) | |
tree | 2f4a31f58a7f117620e95bb85ad00c979088360e | |
parent | 40a2fd6fc1dff7786b70a397e96c094407f1ea1a (diff) | |
download | linux-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.c | 7 | ||||
-rw-r--r-- | fs/smb/client/xattr.c | 54 |
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 |