Permalink
Browse files

Fix ambiguous parsing of *node* entries in /sys.

The code used to use strstr(..., "node") while iterating over
sysfs directories such as /sys/devices/system/cpu/cpu*.
It then made an assumption that the entry would start with "node",
which is not necessarily the case (e.g. the "firmware_node" entry).

The code happened to work for as long as the node[0-9]* entry
would be processed before the "firmware_node" entry shows up.

A change to the linux kernel "end_name_hash" function resulted
in a different hash, and ultimately in a different order
by which entries were returned by readdir(3).

This led to the exposure of this bug.

Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
  • Loading branch information...
gerd-rausch committed Oct 18, 2018
1 parent ca8c12f commit 721460664afad79e2d96bbcb173eda68eed9743b
Showing with 12 additions and 4 deletions.
  1. +8 −3 cputree.c
  2. +4 −1 numa.c
@@ -368,9 +368,14 @@ static void do_one_cpu(char *path)
entry = readdir(dir);
if (!entry)
break;
if (strstr(entry->d_name, "node")) {
nodeid = strtoul(&entry->d_name[4], NULL, 10);
break;
if (strncmp(entry->d_name, "node", 4) == 0) {
char *end;
int num;
num = strtol(entry->d_name + 4, &end, 10);
if (!*end && num >= 0) {
nodeid = num;
break;
}
}
} while (entry);
closedir(dir);
5 numa.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>
@@ -115,7 +116,9 @@ void build_numa_node_list(void)
entry = readdir(dir);
if (!entry)
break;
if ((entry->d_type == DT_DIR) && (strstr(entry->d_name, "node"))) {
if ((entry->d_type == DT_DIR) &&
(strncmp(entry->d_name, "node", 4) == 0) &&
isdigit(entry->d_name[4])) {
add_one_node(entry->d_name);
}
} while (entry);

0 comments on commit 7214606

Please sign in to comment.