Messages in this thread Patch in this message | | | From | Caizhiyong <> | Subject | [PATCH] block: cmdline-parser: perfect cmdline format checking | Date | Tue, 12 Nov 2013 08:19:13 +0000 |
| |
From: Cai Zhiyong <caizhiyong@huawei.com> Date: Tue, 12 Nov 2013 15:50:42 +0800 Subject: [PATCH] block: cmdline-parser: perfect cmdline format checking
-Fix compile warning with value and function undeclared. this reported by <fengguang.wu@intel.com> and Randy Dunlap <rdunlap@infradead.org>
-perfect cmdline format checking, make the error information clear for understand, make this lib fully equivalent to the old parser in drivers/mtd/cmdlinepart.c
I tested each branch of this patch change, it is ok.
Signed-off-by: Cai Zhiyong <caizhiyong@huawei.com> --- block/cmdline-parser.c | 83 +++++++++++++++++++++++++++++++----------- include/linux/cmdline-parser.h | 1 + 2 files changed, 62 insertions(+), 22 deletions(-)
diff --git a/block/cmdline-parser.c b/block/cmdline-parser.c index 9dbc67e..4833936 100644 --- a/block/cmdline-parser.c +++ b/block/cmdline-parser.c @@ -4,12 +4,17 @@ * Written by Cai Zhiyong <caizhiyong@huawei.com> * */ +#define pr_fmt(fmt) "cmdline-parser: " fmt + #include <linux/export.h> #include <linux/cmdline-parser.h> +#include <linux/slab.h> static int parse_subpart(struct cmdline_subpart **subpart, char *partdef) { int ret = 0; + int lastpart = 0; + char *partorg = partdef; struct cmdline_subpart *new_subpart; *subpart = NULL; @@ -21,10 +26,12 @@ static int parse_subpart(struct cmdline_subpart **subpart, char *partdef) if (*partdef == '-') { new_subpart->size = (sector_t)(~0ULL); partdef++; + lastpart = 1; } else { new_subpart->size = (sector_t)memparse(partdef, &partdef); if (new_subpart->size < (sector_t)PAGE_SIZE) { - pr_warn("cmdline partition size is invalid."); + pr_warn("partition '%s' size '0x%llx' too small.\n", + partorg, new_subpart->size); ret = -EINVAL; goto fail; } @@ -42,13 +49,19 @@ static int parse_subpart(struct cmdline_subpart **subpart, char *partdef) char *next = strchr(++partdef, ')'); if (!next) { - pr_warn("cmdline partition format is invalid."); + pr_warn("partition '%s' has no closing ')' found in partition name.\n", + partorg); ret = -EINVAL; goto fail; } - length = min_t(int, next - partdef, - sizeof(new_subpart->name) - 1); + length = (int)(next - partdef); + if (length > sizeof(new_subpart->name) - 1) { + pr_warn("partition '%s' partition name too long, truncating.\n", + partorg); + length = sizeof(new_subpart->name) - 1; + } + strncpy(new_subpart->name, partdef, length); new_subpart->name[length] = '\0'; @@ -68,8 +81,15 @@ static int parse_subpart(struct cmdline_subpart **subpart, char *partdef) partdef += 2; } + if (*partdef) { + pr_warn("partition '%s' has bad character '%c' after partition.\n", + partorg, *partdef); + ret = -EINVAL; + goto fail; + } + *subpart = new_subpart; - return 0; + return lastpart; fail: kfree(new_subpart); return ret; @@ -86,14 +106,13 @@ static void free_subpart(struct cmdline_parts *parts) } } -static int parse_parts(struct cmdline_parts **parts, const char *bdevdef) +static int parse_parts(struct cmdline_parts **parts, char *bdevdef) { int ret = -EINVAL; char *next; int length; struct cmdline_subpart **next_subpart; struct cmdline_parts *newparts; - char buf[BDEVNAME_SIZE + 32 + 4]; *parts = NULL; @@ -102,14 +121,21 @@ static int parse_parts(struct cmdline_parts **parts, const char *bdevdef) return -ENOMEM; next = strchr(bdevdef, ':'); - if (!next) { - pr_warn("cmdline partition has no block device."); + if (!next || next == bdevdef) { + pr_warn("partition '%s' has no block device.\n", bdevdef); goto fail; } - length = min_t(int, next - bdevdef, sizeof(newparts->name) - 1); + length = (int)(next - bdevdef); + if (length > sizeof(newparts->name) - 1) { + pr_warn("partition '%s' device name too long, truncating.\n", + bdevdef); + length = sizeof(newparts->name) - 1; + } + strncpy(newparts->name, bdevdef, length); newparts->name[length] = '\0'; + newparts->nr_subparts = 0; next_subpart = &newparts->subpart; @@ -117,23 +143,25 @@ static int parse_parts(struct cmdline_parts **parts, const char *bdevdef) while (next && *(++next)) { bdevdef = next; next = strchr(bdevdef, ','); + if (next) + *next = '\0'; - length = (!next) ? (sizeof(buf) - 1) : - min_t(int, next - bdevdef, sizeof(buf) - 1); - - strncpy(buf, bdevdef, length); - buf[length] = '\0'; - - ret = parse_subpart(next_subpart, buf); - if (ret) + ret = parse_subpart(next_subpart, bdevdef); + if (ret < 0) { goto fail; + } else if (ret > 0 && next) { + pr_warn("no partitions allowed after a fill-up partition.\n"); + ret = -EINVAL; + goto fail; + } newparts->nr_subparts++; next_subpart = &(*next_subpart)->next_subpart; } if (!newparts->subpart) { - pr_warn("cmdline partition has no valid partition."); + pr_warn("block device '%s' has no valid partition.\n", + newparts->name); ret = -EINVAL; goto fail; } @@ -192,7 +220,7 @@ int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline) } if (!*parts) { - pr_warn("cmdline partition has no valid partition."); + pr_warn("no found valid partition.\n"); ret = -EINVAL; goto fail; } @@ -237,11 +265,22 @@ int cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size, else from = subpart->from; - if (from >= disk_size) + if (subpart->name[0] == '\0') + snprintf(subpart->name, sizeof(subpart->name), + "partition%03d", slot); + + if (from >= disk_size) { + pr_warn("partition '%s' offset exceeds device '%s' size '0x%llx', ignoring.\n", + subpart->name, parts->name, disk_size); break; + } - if (subpart->size > (disk_size - from)) + if (subpart->size > (disk_size - from)) { + if (subpart->size != (sector_t)(~0ULL)) + pr_warn("partition '%s' size exceeds device '%s' size '0x%llx', truncating.\n", + subpart->name, parts->name, disk_size); subpart->size = disk_size - from; + } from += subpart->size; diff --git a/include/linux/cmdline-parser.h b/include/linux/cmdline-parser.h index 43b65a9..c6491b2 100644 --- a/include/linux/cmdline-parser.h +++ b/include/linux/cmdline-parser.h @@ -8,6 +8,7 @@ #define CMDLINEPARSEH #include <linux/blkdev.h> +#include <linux/fs.h> /* partition flags */ #define PF_RDONLY 0x01 /* Device is read only */ -- 1.8.1.5
| |