Messages in this thread Patch in this message | | | From | Caizhiyong <> | Subject | [PATCH] block: cmdline-parser: perfect cmdline format checking | Date | Sat, 9 Nov 2013 11:45:14 +0000 |
| |
From: Cai Zhiyong <caizhiyong@huawei.com> Date: Sat, 9 Nov 2013 19:27:38 +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
Signed-off-by: Cai Zhiyong <caizhiyong@huawei.com> --- block/cmdline-parser.c | 86 +++++++++++++++++++++++++++++++----------- include/linux/cmdline-parser.h | 1 + 2 files changed, 65 insertions(+), 22 deletions(-)
diff --git a/block/cmdline-parser.c b/block/cmdline-parser.c index 9dbc67e..39b6cf4 100644 --- a/block/cmdline-parser.c +++ b/block/cmdline-parser.c @@ -6,10 +6,15 @@ */ #include <linux/export.h> #include <linux/cmdline-parser.h> +#include <linux/slab.h> + +#define PARSER "cmdline-parser: " 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(PARSER "partition '%s' size '0x%llx' too small.", + 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(PARSER "partition '%s' has no closing ')' " + "found in partition name.", 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(PARSER "partition '%s' partition name too long," + " truncating.", 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(PARSER "partition '%s' has bad character '%c' after" + " partition.", 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(PARSER "partition '%s' has no block device.", 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(PARSER "partition '%s' device name too long, " + "truncating.", 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,26 @@ 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(PARSER "no partitions allowed after a " + "fill-up partition."); + 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(PARSER "block device '%s' has no valid" + " partition.", newparts->name); ret = -EINVAL; goto fail; } @@ -192,7 +221,7 @@ int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline) } if (!*parts) { - pr_warn("cmdline partition has no valid partition."); + pr_warn(PARSER "no found valid partition."); ret = -EINVAL; goto fail; } @@ -237,11 +266,24 @@ 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(PARSER "partition '%s' offset exceeds device" + " '%s' size '0x%llx', ignoring.", + 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(PARSER "partition '%s' size exceeds " + "device '%s' size '0x%llx', truncating.", + 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
| |