From 108cfe0b0bae24c9378a447145c31fe27694235d Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Fri, 18 Nov 2011 19:34:02 +0000 Subject: [PATCH] Check target type name for DM_MAX_TYPE_NAME length Avoid creation of target type name when it's longer then DM_MAX_TYPE_NAME (noticed by static analyzer where the sp.target_type might be missing '\0' at the end.) Before patch: $> dmsetup create long 0 1000 looooooooooooooooooooooooooong ^D device-mapper: reload ioctl failed: Invalid argument After patch: $> dmsetup create xxx 0 1000 looooooooooooooooooooooooooong Target type name looooooooooooooooooooooooooong is too long. Command failed --- WHATS_NEW_DM | 1 + libdm/ioctl/libdm-iface.c | 32 ++++++++++++++++++++------------ libdm/libdm-common.c | 3 +-- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 40959714f..15b88782b 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.68 - ================================== + Add test for max length (DM_MAX_TYPE_NAME) of target type name. Include a copy of kernel DM documentation in doc/kernel. Improve man page style for dmsetup. Fix _get_proc_number to be tolerant of malformed /proc/misc entries. diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index a0fa6402a..33c4e37e7 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -853,9 +853,14 @@ int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) struct target *create_target(uint64_t start, uint64_t len, const char *type, const char *params) { - struct target *t = dm_zalloc(sizeof(*t)); + struct target *t; + + if (strlen(type) >= DM_MAX_TYPE_NAME) { + log_error("Target type name %s is too long.", type); + return NULL; + } - if (!t) { + if (!(t = dm_zalloc(sizeof(*t)))) { log_error("create_target: malloc(%" PRIsize_t ") failed", sizeof(*t)); return NULL; @@ -889,19 +894,24 @@ static char *_add_target(struct target *t, char *out, char *end) size_t sp_size = sizeof(struct dm_target_spec); int len; - out += sp_size; - if (out >= end) - return_NULL; + if (strlen(t->type) >= sizeof(sp.target_type)) { + log_error("Target type name %s is too long.", t->type); + return NULL; + } sp.status = 0; sp.sector_start = t->start; sp.length = t->length; - strncpy(sp.target_type, t->type, sizeof(sp.target_type)); + strncpy(sp.target_type, t->type, sizeof(sp.target_type) - 1); + sp.target_type[sizeof(sp.target_type) - 1] = '\0'; + out += sp_size; len = strlen(t->params); - if ((out + len + 1) >= end) - return_NULL; + if ((out >= end) || (out + len + 1) >= end) { + log_error("Ran out of memory building ioctl parameter"); + return NULL; + } strcpy(out, t->params); out += len + 1; @@ -1110,10 +1120,8 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) e = (char *) dmi + len; for (t = dmt->head; t; t = t->next) - if (!(b = _add_target(t, b, e))) { - log_error("Ran out of memory building ioctl parameter"); - goto bad; - } + if (!(b = _add_target(t, b, e))) + goto_bad; if (dmt->newname) strcpy(b, dmt->newname); diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c index 23539d72a..4f438bd26 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -407,9 +407,8 @@ int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, const char *ttype, const char *params) { struct target *t = create_target(start, size, ttype, params); - if (!t) - return 0; + return_0; if (!dmt->head) dmt->head = dmt->tail = t; -- 2.43.5