From 0436d4a1f28523f8c48adc18956857e69eaf1b8f Mon Sep 17 00:00:00 2001 From: "Szczerbik, Przemyslaw" Date: Fri, 27 Sep 2019 07:39:50 +0100 Subject: [PATCH] Check return value of scandir On error, scandir returns -1 and does not allocate memory for namelist array. In some places in the code return value of scandir call is not checked. This causes nvme-cli to attempt to free() an uninitialized pointer, which subsequently leads to segmentation fault. To address this issue, check return value of scandir calls throughout the code. Signed-off-by: Szczerbik, Przemyslaw --- nvme-topology.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/nvme-topology.c b/nvme-topology.c index db48b8a5..176619d3 100644 --- a/nvme-topology.c +++ b/nvme-topology.c @@ -150,7 +150,12 @@ static int scan_ctrl(struct nvme_ctrl *c, char *p) c->transport = get_nvme_ctrl_attr(path, "transport"); c->state = get_nvme_ctrl_attr(path, "state"); - c->nr_namespaces = scandir(path, &ns, scan_namespace_filter, alphasort); + ret = scandir(path, &ns, scan_namespace_filter, alphasort); + if (ret == -1) { + fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); + return errno; + } + c->nr_namespaces = ret; c->namespaces = calloc(c->nr_namespaces, sizeof(*n)); for (i = 0; i < c->nr_namespaces; i++) { n = &c->namespaces[i]; @@ -195,7 +200,12 @@ static int scan_subsystem(struct nvme_subsystem *s) return ret; s->subsysnqn = get_nvme_subsnqn(path); - s->nr_ctrls = scandir(path, &ctrls, scan_ctrls_filter, alphasort); + ret = scandir(path, &ctrls, scan_ctrls_filter, alphasort); + if (ret == -1) { + fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); + return errno; + } + s->nr_ctrls = ret; s->ctrls = calloc(s->nr_ctrls, sizeof(*c)); for (i = 0; i < s->nr_ctrls; i++) { c = &s->ctrls[i]; @@ -208,7 +218,12 @@ static int scan_subsystem(struct nvme_subsystem *s) free(ctrls[i]); free(ctrls); - s->nr_namespaces = scandir(path, &ns, scan_namespace_filter, alphasort); + ret = scandir(path, &ns, scan_namespace_filter, alphasort); + if (ret == -1) { + fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); + return errno; + } + s->nr_namespaces = ret; s->namespaces = calloc(s->nr_namespaces, sizeof(*n)); for (i = 0; i < s->nr_namespaces; i++) { n = &s->namespaces[i]; @@ -264,15 +279,15 @@ static int legacy_list(struct nvme_topology *t) struct nvme_ctrl *c; struct nvme_subsystem *s; struct nvme_namespace *n; - struct dirent **devices, **namespaces; + struct dirent **devices, **namespaces; int ret = 0, fd, i; char *path; t->nr_subsystems = scandir(dev, &devices, scan_ctrls_filter, alphasort); - if (t->nr_subsystems < 0) { + if (t->nr_subsystems < 0) { fprintf(stderr, "no NVMe device(s) detected.\n"); return t->nr_subsystems; - } + } t->subsystems = calloc(t->nr_subsystems, sizeof(*s)); for (i = 0; i < t->nr_subsystems; i++) { -- 2.50.1