|
Michal Schmidt |
514221 |
From 5075b961a29ff9c418e1fefe78432e95dd0a5fcc Mon Sep 17 00:00:00 2001
|
|
Michal Schmidt |
514221 |
From: Michal Schmidt <mschmidt@redhat.com>
|
|
Michal Schmidt |
514221 |
Date: Wed, 1 Feb 2023 22:41:06 +0100
|
|
Michal Schmidt |
514221 |
Subject: [PATCH 1/3] util: fix overflow in remap_node_name()
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
The function remap_node_name() assumes the parameter 'nodedesc' is at
|
|
Michal Schmidt |
514221 |
least IB_SMP_DATA_SIZE + 1 (i.e. 65) bytes long, because it passes it to
|
|
Michal Schmidt |
514221 |
clean_nodedesc() that writes a nul-terminator to it at offset
|
|
Michal Schmidt |
514221 |
IB_SMP_DATA_SIZE. Callers in infiniband-diags/saquery.c pass
|
|
Michal Schmidt |
514221 |
a (struct ib_node_desc_t).description as the argument, which is only
|
|
Michal Schmidt |
514221 |
IB_NODE_DESCRIPTION_SIZE (i.e. 64) bytes long. This is an overflow.
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
An odd thing about remap_node_name() is that it may (but does not
|
|
Michal Schmidt |
514221 |
always) rewrite the nodedesc in-place. Callers do not appear to
|
|
Michal Schmidt |
514221 |
appreciate this behavior. Most of them are various print_* and dump_*
|
|
Michal Schmidt |
514221 |
functions where rewriting the input makes no sense. Some callers make a
|
|
Michal Schmidt |
514221 |
local copy of the nodedesc first, possibly to protect the original.
|
|
Michal Schmidt |
514221 |
One caller (infiniband-diags/saquery.c:print_node_records()) checks if
|
|
Michal Schmidt |
514221 |
either the original description or the remapped one matches a given
|
|
Michal Schmidt |
514221 |
requested_name - so it looks like it prefers the original to be
|
|
Michal Schmidt |
514221 |
not rewritten.
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
Let's make remap_node_name() a bit safer and more convenient to use.
|
|
Michal Schmidt |
514221 |
Allocate a fixed-sized copy first. Then use strncpy to copy from
|
|
Michal Schmidt |
514221 |
'nodedesc', never reading more than IB_SMP_DATA_SIZE (64) bytes.
|
|
Michal Schmidt |
514221 |
Apply clean_nodedesc() on the correctly-sized copy. This solves the
|
|
Michal Schmidt |
514221 |
overflow bug. Also, the in-place rewrite of 'nodedesc' is gone and it
|
|
Michal Schmidt |
514221 |
can become a (const char*).
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
The overflow was found by a static checker (covscan).
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
Fixes: d974c4e398d2 ("Fix max length of node description (ibnetdiscover and smpquery)")
|
|
Michal Schmidt |
514221 |
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
|
|
Michal Schmidt |
514221 |
---
|
|
Michal Schmidt |
514221 |
util/node_name_map.c | 12 +++++++++---
|
|
Michal Schmidt |
514221 |
util/node_name_map.h | 3 +--
|
|
Michal Schmidt |
514221 |
2 files changed, 10 insertions(+), 5 deletions(-)
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
diff --git a/util/node_name_map.c b/util/node_name_map.c
|
|
Michal Schmidt |
514221 |
index 30b73eb1448e..511cb92ef19c 100644
|
|
Michal Schmidt |
514221 |
--- a/util/node_name_map.c
|
|
Michal Schmidt |
514221 |
+++ b/util/node_name_map.c
|
|
Michal Schmidt |
514221 |
@@ -95,7 +95,7 @@ void close_node_name_map(nn_map_t * map)
|
|
Michal Schmidt |
514221 |
free(map);
|
|
Michal Schmidt |
514221 |
}
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
-char *remap_node_name(nn_map_t * map, uint64_t target_guid, char *nodedesc)
|
|
Michal Schmidt |
514221 |
+char *remap_node_name(nn_map_t * map, uint64_t target_guid, const char *nodedesc)
|
|
Michal Schmidt |
514221 |
{
|
|
Michal Schmidt |
514221 |
char *rc = NULL;
|
|
Michal Schmidt |
514221 |
name_map_item_t *item = NULL;
|
|
Michal Schmidt |
514221 |
@@ -108,8 +108,14 @@ char *remap_node_name(nn_map_t * map, uint64_t target_guid, char *nodedesc)
|
|
Michal Schmidt |
514221 |
rc = strdup(item->name);
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
done:
|
|
Michal Schmidt |
514221 |
- if (rc == NULL)
|
|
Michal Schmidt |
514221 |
- rc = strdup(clean_nodedesc(nodedesc));
|
|
Michal Schmidt |
514221 |
+ if (rc == NULL) {
|
|
Michal Schmidt |
514221 |
+ rc = malloc(IB_SMP_DATA_SIZE + 1);
|
|
Michal Schmidt |
514221 |
+ if (rc) {
|
|
Michal Schmidt |
514221 |
+ strncpy(rc, nodedesc, IB_SMP_DATA_SIZE);
|
|
Michal Schmidt |
514221 |
+ rc[IB_SMP_DATA_SIZE] = '\0';
|
|
Michal Schmidt |
514221 |
+ clean_nodedesc(rc);
|
|
Michal Schmidt |
514221 |
+ }
|
|
Michal Schmidt |
514221 |
+ }
|
|
Michal Schmidt |
514221 |
return (rc);
|
|
Michal Schmidt |
514221 |
}
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
diff --git a/util/node_name_map.h b/util/node_name_map.h
|
|
Michal Schmidt |
514221 |
index e78d274b116e..d83d672782c4 100644
|
|
Michal Schmidt |
514221 |
--- a/util/node_name_map.h
|
|
Michal Schmidt |
514221 |
+++ b/util/node_name_map.h
|
|
Michal Schmidt |
514221 |
@@ -12,8 +12,7 @@ typedef struct nn_map nn_map_t;
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
nn_map_t *open_node_name_map(const char *node_name_map);
|
|
Michal Schmidt |
514221 |
void close_node_name_map(nn_map_t *map);
|
|
Michal Schmidt |
514221 |
-/* NOTE: parameter "nodedesc" may be modified here. */
|
|
Michal Schmidt |
514221 |
-char *remap_node_name(nn_map_t *map, uint64_t target_guid, char *nodedesc);
|
|
Michal Schmidt |
514221 |
+char *remap_node_name(nn_map_t *map, uint64_t target_guid, const char *nodedesc);
|
|
Michal Schmidt |
514221 |
char *clean_nodedesc(char *nodedesc);
|
|
Michal Schmidt |
514221 |
|
|
Michal Schmidt |
514221 |
#endif
|
|
Michal Schmidt |
514221 |
--
|
|
Michal Schmidt |
514221 |
2.39.1
|
|
Michal Schmidt |
514221 |
|