cifs: sanitize multiple delimiters in prepath
Subsystems (3)
PATCH v2 1/1 cifs: sanitize multiple delimiters in prepath
mount.cifs can pass a device with multiple delimiters in it. This will cause rename(2) to fail with ENOENT.
V2:
- Make sanitize_path more readable.
- Fix multiple delimiters between UNC and prepath.
- Avoid a memory leak if a bad user starts putting a lot of delimiters in the path on purpose.
Fixes 24e0a1eff9e2 ("cifs: switch to new mount api")
Cc [email protected] # 5.11+
Signed-off-by Thiago Rafael Becker <[email protected]>
--- fs/cifs/fs_context.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)
fs/cifs/fs_context.c +37 -1
@@ -434,6 +434,42 @@ int smb3_parse_opt(const char *options, const char *key, char **val)return rc; } +/* +* Remove duplicate path delimiters. Windows is supposed to do that +* but there are some bugs that prevent rename from working if there are +* multiple delimiters. +* +* Returns a sanitized duplicate of @path. The caller is responsible for +* cleaning up the original. +*/ +#define IS_DELIM (c) ((c) == '/' || (c) == '\\') +static char *sanitize_path (char *path) +{ +char *cursor1 = path, *cursor2 = path; + +/* skip all prepended delimiters */ +while (IS_DELIM (*cursor1)) + cursor1++; + +/* copy the first letter */ + *cursor2 = *cursor1; + +/* copy the remainder... */ +while (*(cursor1++)) { +/* ... skipping all duplicated delimiters */ +if (IS_DELIM (*cursor1) &&IS_DELIM (*cursor2)) +continue ; + *(++cursor2) = *cursor1; + } + +/* if the last character is a delimiter, skip it */ +if (IS_DELIM (*(cursor2 -1 ))) + cursor2--; + + *(cursor2) ='\0' ; +return kstrdup (path,GFP_KERNEL ); +} +/* * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath * fields with the result. Returns 0 on success and an error otherwise
@@ -493,7 +529,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)if (!*pos)return 0 ; - ctx->prepath =kstrdup (pos,GFP_KERNEL ); + ctx->prepath =sanitize_path (pos);if (!ctx->prepath)return -ENOMEM ;
Signature · 1 line
2.31.1