From 7ca7cad4b5c0967de02b2c332db13d4d4b697811 Mon Sep 17 00:00:00 2001 From: Michal Hlavinka Date: Wed, 16 Jul 2025 12:56:52 +0200 Subject: [PATCH] fix buffer overflow parsing VPD page (RHEL-83471) Resolves: RHEL-83471 --- smartmontools-7.5-a2a45dc.patch | 116 ++++++++++++++++++++++++++++++++ smartmontools.spec | 7 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 smartmontools-7.5-a2a45dc.patch diff --git a/smartmontools-7.5-a2a45dc.patch b/smartmontools-7.5-a2a45dc.patch new file mode 100644 index 0000000..a5e0f2c --- /dev/null +++ b/smartmontools-7.5-a2a45dc.patch @@ -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 diff --git a/smartmontools.spec b/smartmontools.spec index 2fb52e5..273efa2 100644 --- a/smartmontools.spec +++ b/smartmontools.spec @@ -7,7 +7,7 @@ Summary: Tools for monitoring SMART capable hard disks Name: smartmontools Version: 7.4 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 1 License: GPL-2.0-or-later URL: http://smartmontools.sourceforge.net/ @@ -25,6 +25,7 @@ Source8: %{modulename}.fc Patch1: smartmontools-5.38-defaultconf.patch # reported upstream, issue#273, RHEL-44567 Patch2: smartmontools-7.4-fix_sast.patch +Patch3: smartmontools-7.5-a2a45dc.patch BuildRequires: make BuildRequires: gcc-c++ readline-devel ncurses-devel automake util-linux groff gettext @@ -70,6 +71,7 @@ Custom SELinux policy module for smartmontools %setup -q %patch -P 1 -p1 -b .defaultconf %patch -P 2 -p1 -b .fix_sast +%patch -P 3 -p2 -b .a2a45dc cp %{SOURCE5} . %if 0%{?with_selinux} mkdir selinux @@ -170,6 +172,9 @@ fi %changelog +* Wed Jul 16 2025 Michal Hlavinka - 1:7.4-8 +- fix buffer overflow parsing VPD page (RHEL-83471) + * Tue Oct 29 2024 Troy Dawson - 1:7.4-7 - Bump release for October 2024 mass rebuild: Resolves: RHEL-64018