The quilt patch titled Subject: vfs: parse: deal with zero length string value has been removed from the -mm tree. Its filename was vfs-parse-deal-with-zero-length-string-value.patch This patch was dropped because an updated version will be merged ------------------------------------------------------ From: Ian Kent <raven@xxxxxxxxxx> Subject: vfs: parse: deal with zero length string value Date: Tue, 20 Sep 2022 15:26:29 +0800 Parsing an fs string that has zero length should result in the parameter being set to NULL so that downstream processing handles it correctly. For example, the proc mount table processing should print "(none)" in this case to preserve mount record field count, but if the value points to the NULL string this doesn't happen. Link: https://lkml.kernel.org/r/166365878918.39016.12757946948158123324.stgit@xxxxxxxxxxxxxxxxx Signed-off-by: Ian Kent <raven@xxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Carlos Maiolino <cmaiolino@xxxxxxxxxx> Cc: David Howells <dhowells@xxxxxxxxxx> Cc: kernel test robot <oliver.sang@xxxxxxxxx> Cc: Miklos Szeredi <miklos@xxxxxxxxxx> Cc: Siddhesh Poyarekar <siddhesh@xxxxxxxxxx> Cc: Theodore Ts'o <tytso@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/fs_context.c | 17 ++++++++++++----- fs/fs_parser.c | 16 ++++++++++++++++ include/linux/fs_context.h | 3 ++- 3 files changed, 30 insertions(+), 6 deletions(-) --- a/fs/fs_context.c~vfs-parse-deal-with-zero-length-string-value +++ a/fs/fs_context.c @@ -96,7 +96,9 @@ int vfs_parse_fs_param_source(struct fs_ if (strcmp(param->key, "source") != 0) return -ENOPARAM; - if (param->type != fs_value_is_string) + /* source value may be NULL */ + if (param->type != fs_value_is_string && + param->type != fs_value_is_empty) return invalf(fc, "Non-string source"); if (fc->source) @@ -175,10 +177,15 @@ int vfs_parse_fs_string(struct fs_contex }; if (value) { - param.string = kmemdup_nul(value, v_size, GFP_KERNEL); - if (!param.string) - return -ENOMEM; - param.type = fs_value_is_string; + if (!v_size) { + param.string = NULL; + param.type = fs_value_is_empty; + } else { + param.string = kmemdup_nul(value, v_size, GFP_KERNEL); + if (!param.string) + return -ENOMEM; + param.type = fs_value_is_string; + } } ret = vfs_parse_fs_param(fc, ¶m); --- a/fs/fs_parser.c~vfs-parse-deal-with-zero-length-string-value +++ a/fs/fs_parser.c @@ -197,6 +197,8 @@ int fs_param_is_bool(struct p_log *log, struct fs_parameter *param, struct fs_parse_result *result) { int b; + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string) return fs_param_bad_value(log, param); if (!*param->string && (p->flags & fs_param_can_be_empty)) @@ -213,6 +215,8 @@ int fs_param_is_u32(struct p_log *log, c struct fs_parameter *param, struct fs_parse_result *result) { int base = (unsigned long)p->data; + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string) return fs_param_bad_value(log, param); if (!*param->string && (p->flags & fs_param_can_be_empty)) @@ -226,6 +230,8 @@ EXPORT_SYMBOL(fs_param_is_u32); int fs_param_is_s32(struct p_log *log, const struct fs_parameter_spec *p, struct fs_parameter *param, struct fs_parse_result *result) { + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string) return fs_param_bad_value(log, param); if (!*param->string && (p->flags & fs_param_can_be_empty)) @@ -239,6 +245,8 @@ EXPORT_SYMBOL(fs_param_is_s32); int fs_param_is_u64(struct p_log *log, const struct fs_parameter_spec *p, struct fs_parameter *param, struct fs_parse_result *result) { + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string) return fs_param_bad_value(log, param); if (!*param->string && (p->flags & fs_param_can_be_empty)) @@ -253,6 +261,8 @@ int fs_param_is_enum(struct p_log *log, struct fs_parameter *param, struct fs_parse_result *result) { const struct constant_table *c; + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string) return fs_param_bad_value(log, param); if (!*param->string && (p->flags & fs_param_can_be_empty)) @@ -268,6 +278,8 @@ EXPORT_SYMBOL(fs_param_is_enum); int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p, struct fs_parameter *param, struct fs_parse_result *result) { + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_string || (!*param->string && !(p->flags & fs_param_can_be_empty))) return fs_param_bad_value(log, param); @@ -278,6 +290,8 @@ EXPORT_SYMBOL(fs_param_is_string); int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p, struct fs_parameter *param, struct fs_parse_result *result) { + if (param->type == fs_value_is_empty) + return 0; if (param->type != fs_value_is_blob) return fs_param_bad_value(log, param); return 0; @@ -287,6 +301,8 @@ EXPORT_SYMBOL(fs_param_is_blob); int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p, struct fs_parameter *param, struct fs_parse_result *result) { + if (param->type == fs_value_is_empty) + return 0; switch (param->type) { case fs_value_is_string: if ((!*param->string && !(p->flags & fs_param_can_be_empty)) || --- a/include/linux/fs_context.h~vfs-parse-deal-with-zero-length-string-value +++ a/include/linux/fs_context.h @@ -50,7 +50,8 @@ enum fs_context_phase { */ enum fs_value_type { fs_value_is_undefined, - fs_value_is_flag, /* Value not given a value */ + fs_value_is_flag, /* Does not take a value */ + fs_value_is_empty, /* Value is not given */ fs_value_is_string, /* Value is a string */ fs_value_is_blob, /* Value is a binary blob */ fs_value_is_filename, /* Value is a filename* + dirfd */ _ Patches currently in -mm which might be from raven@xxxxxxxxxx are