|
|
b302d8 |
From 721460664afad79e2d96bbcb173eda68eed9743b Mon Sep 17 00:00:00 2001
|
|
|
b302d8 |
From: Gerd Rausch <gerd.rausch@oracle.com>
|
|
|
b302d8 |
Date: Thu, 18 Oct 2018 11:21:40 -0700
|
|
|
b302d8 |
Subject: [PATCH] Fix ambiguous parsing of *node* entries in /sys.
|
|
|
b302d8 |
|
|
|
b302d8 |
The code used to use strstr(..., "node") while iterating over
|
|
|
b302d8 |
sysfs directories such as /sys/devices/system/cpu/cpu*.
|
|
|
b302d8 |
It then made an assumption that the entry would start with "node",
|
|
|
b302d8 |
which is not necessarily the case (e.g. the "firmware_node" entry).
|
|
|
b302d8 |
|
|
|
b302d8 |
The code happened to work for as long as the node[0-9]* entry
|
|
|
b302d8 |
would be processed before the "firmware_node" entry shows up.
|
|
|
b302d8 |
|
|
|
b302d8 |
A change to the linux kernel "end_name_hash" function resulted
|
|
|
b302d8 |
in a different hash, and ultimately in a different order
|
|
|
b302d8 |
by which entries were returned by readdir(3).
|
|
|
b302d8 |
|
|
|
b302d8 |
This led to the exposure of this bug.
|
|
|
b302d8 |
|
|
|
b302d8 |
Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
|
|
|
b302d8 |
---
|
|
|
b302d8 |
cputree.c | 11 ++++++++---
|
|
|
b302d8 |
numa.c | 5 ++++-
|
|
|
b302d8 |
2 files changed, 12 insertions(+), 4 deletions(-)
|
|
|
b302d8 |
|
|
|
b302d8 |
diff --git a/cputree.c b/cputree.c
|
|
|
b302d8 |
index c88143f..f08ce84 100644
|
|
|
b302d8 |
--- a/cputree.c
|
|
|
b302d8 |
+++ b/cputree.c
|
|
|
b302d8 |
@@ -368,9 +368,14 @@ static void do_one_cpu(char *path)
|
|
|
b302d8 |
entry = readdir(dir);
|
|
|
b302d8 |
if (!entry)
|
|
|
b302d8 |
break;
|
|
|
b302d8 |
- if (strstr(entry->d_name, "node")) {
|
|
|
b302d8 |
- nodeid = strtoul(&entry->d_name[4], NULL, 10);
|
|
|
b302d8 |
- break;
|
|
|
b302d8 |
+ if (strncmp(entry->d_name, "node", 4) == 0) {
|
|
|
b302d8 |
+ char *end;
|
|
|
b302d8 |
+ int num;
|
|
|
b302d8 |
+ num = strtol(entry->d_name + 4, &end, 10);
|
|
|
b302d8 |
+ if (!*end && num >= 0) {
|
|
|
b302d8 |
+ nodeid = num;
|
|
|
b302d8 |
+ break;
|
|
|
b302d8 |
+ }
|
|
|
b302d8 |
}
|
|
|
b302d8 |
} while (entry);
|
|
|
b302d8 |
closedir(dir);
|
|
|
b302d8 |
diff --git a/numa.c b/numa.c
|
|
|
b302d8 |
index cd67ec8..f0b1a98 100644
|
|
|
b302d8 |
--- a/numa.c
|
|
|
b302d8 |
+++ b/numa.c
|
|
|
b302d8 |
@@ -29,6 +29,7 @@
|
|
|
b302d8 |
#include <unistd.h>
|
|
|
b302d8 |
#include <stdlib.h>
|
|
|
b302d8 |
#include <stdio.h>
|
|
|
b302d8 |
+#include <ctype.h>
|
|
|
b302d8 |
#include <sys/types.h>
|
|
|
b302d8 |
#include <dirent.h>
|
|
|
b302d8 |
|
|
|
b302d8 |
@@ -115,7 +116,9 @@ void build_numa_node_list(void)
|
|
|
b302d8 |
entry = readdir(dir);
|
|
|
b302d8 |
if (!entry)
|
|
|
b302d8 |
break;
|
|
|
b302d8 |
- if ((entry->d_type == DT_DIR) && (strstr(entry->d_name, "node"))) {
|
|
|
b302d8 |
+ if ((entry->d_type == DT_DIR) &&
|
|
|
b302d8 |
+ (strncmp(entry->d_name, "node", 4) == 0) &&
|
|
|
b302d8 |
+ isdigit(entry->d_name[4])) {
|
|
|
b302d8 |
add_one_node(entry->d_name);
|
|
|
b302d8 |
}
|
|
|
b302d8 |
} while (entry);
|
|
|
b302d8 |
--
|
|
|
b302d8 |
2.21.0
|
|
|
b302d8 |
|