Skip to content

Commit 0436d4a

Browse files
committed
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 <[email protected]>
1 parent 5c1ab09 commit 0436d4a

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

nvme-topology.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,12 @@ static int scan_ctrl(struct nvme_ctrl *c, char *p)
150150
c->transport = get_nvme_ctrl_attr(path, "transport");
151151
c->state = get_nvme_ctrl_attr(path, "state");
152152

153-
c->nr_namespaces = scandir(path, &ns, scan_namespace_filter, alphasort);
153+
ret = scandir(path, &ns, scan_namespace_filter, alphasort);
154+
if (ret == -1) {
155+
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
156+
return errno;
157+
}
158+
c->nr_namespaces = ret;
154159
c->namespaces = calloc(c->nr_namespaces, sizeof(*n));
155160
for (i = 0; i < c->nr_namespaces; i++) {
156161
n = &c->namespaces[i];
@@ -195,7 +200,12 @@ static int scan_subsystem(struct nvme_subsystem *s)
195200
return ret;
196201

197202
s->subsysnqn = get_nvme_subsnqn(path);
198-
s->nr_ctrls = scandir(path, &ctrls, scan_ctrls_filter, alphasort);
203+
ret = scandir(path, &ctrls, scan_ctrls_filter, alphasort);
204+
if (ret == -1) {
205+
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
206+
return errno;
207+
}
208+
s->nr_ctrls = ret;
199209
s->ctrls = calloc(s->nr_ctrls, sizeof(*c));
200210
for (i = 0; i < s->nr_ctrls; i++) {
201211
c = &s->ctrls[i];
@@ -208,7 +218,12 @@ static int scan_subsystem(struct nvme_subsystem *s)
208218
free(ctrls[i]);
209219
free(ctrls);
210220

211-
s->nr_namespaces = scandir(path, &ns, scan_namespace_filter, alphasort);
221+
ret = scandir(path, &ns, scan_namespace_filter, alphasort);
222+
if (ret == -1) {
223+
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
224+
return errno;
225+
}
226+
s->nr_namespaces = ret;
212227
s->namespaces = calloc(s->nr_namespaces, sizeof(*n));
213228
for (i = 0; i < s->nr_namespaces; i++) {
214229
n = &s->namespaces[i];
@@ -264,15 +279,15 @@ static int legacy_list(struct nvme_topology *t)
264279
struct nvme_ctrl *c;
265280
struct nvme_subsystem *s;
266281
struct nvme_namespace *n;
267-
struct dirent **devices, **namespaces;
282+
struct dirent **devices, **namespaces;
268283
int ret = 0, fd, i;
269284
char *path;
270285

271286
t->nr_subsystems = scandir(dev, &devices, scan_ctrls_filter, alphasort);
272-
if (t->nr_subsystems < 0) {
287+
if (t->nr_subsystems < 0) {
273288
fprintf(stderr, "no NVMe device(s) detected.\n");
274289
return t->nr_subsystems;
275-
}
290+
}
276291

277292
t->subsystems = calloc(t->nr_subsystems, sizeof(*s));
278293
for (i = 0; i < t->nr_subsystems; i++) {

0 commit comments

Comments
 (0)