fix buffer overflow parsing VPD page (RHEL-83471)

Resolves: RHEL-83471
This commit is contained in:
Michal Hlavinka 2025-07-16 12:56:52 +02:00
parent 03b8f70707
commit 7ca7cad4b5
2 changed files with 122 additions and 1 deletions

View File

@ -0,0 +1,116 @@
diff --git a/smartmontools/scsicmds.cpp.fix b/smartmontools/scsicmds.cpp
index f5579156f..c4569f1c0 100644
--- a/smartmontools/scsicmds.cpp.fix
+++ b/smartmontools/scsicmds.cpp
@@ -755,6 +755,7 @@ scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
return -1;
}
+#define SLEN(a, b) ((a) > (b) ? ((a) - (b)) : 0)
s[0] = '\0';
int si = 0;
int have_scsi_ns = 0;
@@ -764,7 +765,7 @@ scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
const unsigned char * ucp = b + off;
int i_len = ucp[3];
if ((off + i_len + 4) > blen) {
- snprintf(s+si, slen-si, "error: designator length");
+ snprintf(s+si, SLEN(slen, si), "error: designator length");
return -1;
}
int assoc = ((ucp[1] >> 4) & 0x3);
@@ -783,52 +784,52 @@ scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
break;
case 2: /* EUI-64 based */
if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
- snprintf(s+si, slen-si, "error: EUI-64 length");
+ snprintf(s+si, SLEN(slen, si), "error: EUI-64 length");
return -1;
}
if (have_scsi_ns)
si = 0;
- si += snprintf(s+si, slen-si, "0x");
+ si += snprintf(s+si, SLEN(slen, si), "0x");
for (int m = 0; m < i_len; ++m)
- si += snprintf(s+si, slen-si, "%02x", (unsigned int)ip[m]);
+ si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
break;
case 3: /* NAA */
if (1 != c_set) {
- snprintf(s+si, slen-si, "error: NAA bad code_set");
+ snprintf(s+si, SLEN(slen, si), "error: NAA bad code_set");
return -1;
}
naa = (ip[0] >> 4) & 0xff;
if ((naa < 2) || (naa > 6) || (4 == naa)) {
- snprintf(s+si, slen-si, "error: unexpected NAA");
+ snprintf(s+si, SLEN(slen, si), "error: unexpected NAA");
return -1;
}
if (have_scsi_ns)
si = 0;
if (2 == naa) { /* NAA IEEE Extended */
if (8 != i_len) {
- snprintf(s+si, slen-si, "error: NAA 2 length");
+ snprintf(s+si, SLEN(slen, si), "error: NAA 2 length");
return -1;
}
- si += snprintf(s+si, slen-si, "0x");
+ si += snprintf(s+si, SLEN(slen, si), "0x");
for (int m = 0; m < 8; ++m)
- si += snprintf(s+si, slen-si, "%02x", (unsigned int)ip[m]);
+ si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
} else if ((3 == naa ) || (5 == naa)) {
/* NAA=3 Locally assigned; NAA=5 IEEE Registered */
if (8 != i_len) {
- snprintf(s+si, slen-si, "error: NAA 3 or 5 length");
+ snprintf(s+si, SLEN(slen, si), "error: NAA 3 or 5 length");
return -1;
}
- si += snprintf(s+si, slen-si, "0x");
+ si += snprintf(s+si, SLEN(slen, si), "0x");
for (int m = 0; m < 8; ++m)
- si += snprintf(s+si, slen-si, "%02x", (unsigned int)ip[m]);
+ si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
} else if (6 == naa) { /* NAA IEEE Registered extended */
if (16 != i_len) {
- snprintf(s+si, slen-si, "error: NAA 6 length");
+ snprintf(s+si, SLEN(slen, si), "error: NAA 6 length");
return -1;
}
- si += snprintf(s+si, slen-si, "0x");
+ si += snprintf(s+si, SLEN(slen, si), "0x");
for (int m = 0; m < 16; ++m)
- si += snprintf(s+si, slen-si, "%02x", (unsigned int)ip[m]);
+ si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
}
break;
case 4: /* Relative target port */
@@ -838,12 +839,12 @@ scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
break;
case 8: /* SCSI name string */
if (3 != c_set) {
- snprintf(s+si, slen-si, "error: SCSI name string");
+ snprintf(s+si, SLEN(slen, si), "error: SCSI name string");
return -1;
}
/* does %s print out UTF-8 ok?? */
if (si == 0) {
- si += snprintf(s+si, slen-si, "%s", (const char *)ip);
+ si += snprintf(s+si, SLEN(slen, si), "%s", (const char *)ip);
++have_scsi_ns;
}
break;
@@ -852,10 +853,11 @@ scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
}
}
if (-2 == u) {
- snprintf(s+si, slen-si, "error: bad structure");
+ snprintf(s+si, SLEN(slen, si), "error: bad structure");
return -1;
}
return 0;
+#undef SLEN
}
/* Sends LOG SENSE command. Returns 0 if ok, 1 if device NOT READY, 2 if

View File

@ -7,7 +7,7 @@
Summary: Tools for monitoring SMART capable hard disks Summary: Tools for monitoring SMART capable hard disks
Name: smartmontools Name: smartmontools
Version: 7.4 Version: 7.4
Release: 7%{?dist} Release: 8%{?dist}
Epoch: 1 Epoch: 1
License: GPL-2.0-or-later License: GPL-2.0-or-later
URL: http://smartmontools.sourceforge.net/ URL: http://smartmontools.sourceforge.net/
@ -25,6 +25,7 @@ Source8: %{modulename}.fc
Patch1: smartmontools-5.38-defaultconf.patch Patch1: smartmontools-5.38-defaultconf.patch
# reported upstream, issue#273, RHEL-44567 # reported upstream, issue#273, RHEL-44567
Patch2: smartmontools-7.4-fix_sast.patch Patch2: smartmontools-7.4-fix_sast.patch
Patch3: smartmontools-7.5-a2a45dc.patch
BuildRequires: make BuildRequires: make
BuildRequires: gcc-c++ readline-devel ncurses-devel automake util-linux groff gettext BuildRequires: gcc-c++ readline-devel ncurses-devel automake util-linux groff gettext
@ -70,6 +71,7 @@ Custom SELinux policy module for smartmontools
%setup -q %setup -q
%patch -P 1 -p1 -b .defaultconf %patch -P 1 -p1 -b .defaultconf
%patch -P 2 -p1 -b .fix_sast %patch -P 2 -p1 -b .fix_sast
%patch -P 3 -p2 -b .a2a45dc
cp %{SOURCE5} . cp %{SOURCE5} .
%if 0%{?with_selinux} %if 0%{?with_selinux}
mkdir selinux mkdir selinux
@ -170,6 +172,9 @@ fi
%changelog %changelog
* Wed Jul 16 2025 Michal Hlavinka <mhlavink@redhat.com> - 1:7.4-8
- fix buffer overflow parsing VPD page (RHEL-83471)
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1:7.4-7 * Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1:7.4-7
- Bump release for October 2024 mass rebuild: - Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018 Resolves: RHEL-64018