Fix buffer overflow in print_hw_addr()

Resolves: RHEL-151420
This commit is contained in:
Martin Osvald 2026-03-31 09:40:06 +02:00
parent 40dc11e51e
commit c4ef4d9a2c
2 changed files with 76 additions and 2 deletions

View File

@ -15,7 +15,7 @@
Summary: Dynamic host configuration protocol software
Name: dhcp
Version: 4.4.2
Release: 20.b1%{?dist}
Release: 21.b1%{?dist}
# NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to
# dcantrell maintaining the package) made incorrect use of the epoch and
@ -24,7 +24,7 @@ Release: 20.b1%{?dist}
Epoch: 12
License: ISC
Url: https://www.isc.org/dhcp/
Source0: ftp://ftp.isc.org/isc/dhcp/%{DHCPVERSION}/dhcp-%{DHCPVERSION}.tar.gz
Source0: https://downloads.isc.org/isc/dhcp/%{DHCPVERSION}/dhcp-%{DHCPVERSION}.tar.gz
Source1: dhclient-script
Source2: README.dhclient.d
Source3: 11-dhclient
@ -69,6 +69,7 @@ Patch31: omshell-hmac-sha512-support.patch
Patch32: CVE-2022-2928.patch
Patch33: CVE-2022-2929.patch
Patch34: dont-drop-bounds-twice.patch
Patch35: fix-buffer-overflow-in-print_hw_addr.patch
BuildRequires: autoconf
@ -512,6 +513,10 @@ done
%endif
%changelog
* Tue Mar 31 2026 Martin Osvald <mosvald@redhat.com> - 12:4.4.2-21.b1
- Fix buffer overflow in print_hw_addr()
Resolves: RHEL-151420
* Wed Jan 07 2026 Martin Osvald <mosvald@redhat.com> - 12:4.4.2-20.b1
- Create /var/lib/dhcpd through systemd-tmpfiles
Resolves: RHEL-134207

View File

@ -0,0 +1,69 @@
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 *,