70 lines
2.1 KiB
Diff
70 lines
2.1 KiB
Diff
From: Martin Osvald <mosvald@redhat.com>
|
|
Date: Thu, 2 Apr 2026 11:10:56 +0200
|
|
Subject: [PATCH] Fix buffer overflow in print_hw_addr() (downstream-only, upstream EOL)
|
|
|
|
The existing print_hw_addr() helper uses a fixed 49-byte buffer, which is
|
|
too small for longer hardware addresses such as InfiniBand (20 bytes). This
|
|
can overflow the static output buffer when formatting addresses as
|
|
colon-separated hexadecimal bytes.
|
|
|
|
Signed-off-by: Martin Osvald <mosvald@redhat.com>
|
|
diff --git a/common/print.c b/common/print.c
|
|
index b42e7bc..7256714 100644
|
|
--- a/common/print.c
|
|
+++ b/common/print.c
|
|
@@ -170,23 +170,37 @@ char *print_base64 (const unsigned char *buf, unsigned len,
|
|
|
|
char *print_hw_addr (htype, hlen, data)
|
|
const int htype;
|
|
- const int hlen;
|
|
+ int hlen;
|
|
const unsigned char *data;
|
|
{
|
|
- static char habuf [49];
|
|
+ /* Buffer sized for InfiniBand (20 bytes): 20 * 3 = 60 chars
|
|
+ * Each byte needs 3 chars "xx:", last ':' replaced by 0 */
|
|
+ static char habuf [60];
|
|
+ int max_bytes = sizeof(habuf) / 3;
|
|
char *s;
|
|
int i;
|
|
|
|
- if (hlen <= 0)
|
|
+ if (hlen <= 0 || data == NULL)
|
|
habuf [0] = 0;
|
|
else {
|
|
+ int orig_hlen = 0;
|
|
+ if (hlen > max_bytes) {
|
|
+ orig_hlen = hlen;
|
|
+ hlen = max_bytes;
|
|
+ }
|
|
+
|
|
s = habuf;
|
|
for (i = 0; i < hlen; i++) {
|
|
sprintf (s, "%02x", data [i]);
|
|
- s += strlen (s);
|
|
+ s += 2;
|
|
*s++ = ':';
|
|
}
|
|
*--s = 0;
|
|
+
|
|
+ if (orig_hlen) {
|
|
+ log_error("Hardware address %s truncated from %d to %d bytes",
|
|
+ habuf, orig_hlen, max_bytes);
|
|
+ }
|
|
}
|
|
return habuf;
|
|
}
|
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
|
index 14161c3..5b1dfd8 100644
|
|
--- a/includes/dhcpd.h
|
|
+++ b/includes/dhcpd.h
|
|
@@ -2618,7 +2618,7 @@ char *quotify_string (const char *, const char *, int);
|
|
char *quotify_buf (const unsigned char *, unsigned, const char,
|
|
const char *, int);
|
|
char *print_base64 (const unsigned char *, unsigned, const char *, int);
|
|
-char *print_hw_addr (const int, const int, const unsigned char *);
|
|
+char *print_hw_addr (const int, int, const unsigned char *);
|
|
void print_lease (struct lease *);
|
|
void dump_raw (const unsigned char *, unsigned);
|
|
void dump_packet_option (struct option_cache *, struct packet *,
|