From: Albert Chu <chu11@llnl.gov>
Subject: ipmi-oem: fix several memory out of bounds errors
References: bsc#1260414 CVE-2026-33554
Patch-Mainline: describe
Git-commit: b03ca4d1bff4626c11db8684564b88cd26a2425d


Found by Zhihan Zheng (chnzzh@outlook.com)


Signed-off-by: Thomas Renninger <trenn@suse.de>
---
 ipmi-oem/ipmi-oem-dell.c       |   12 +++++++++---
 ipmi-oem/ipmi-oem-supermicro.c |    7 ++++++-
 ipmi-oem/ipmi-oem-wistron.c    |    7 ++++++-
 3 files changed, 21 insertions(+), 5 deletions(-)

--- a/ipmi-oem/ipmi-oem-dell.c
+++ b/ipmi-oem/ipmi-oem-dell.c
@@ -7162,7 +7162,7 @@
   uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
   uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
   uint8_t post_code;
-  uint8_t string_length;
+  size_t string_length;
   char post_code_string[IPMI_OEM_STR_BUFLEN + 1];
   int rs_len;
   int rv = -1;
@@ -7217,10 +7217,16 @@
     goto cleanup;
   
   post_code = bytes_rs[2];
-  string_length = bytes_rs[3];
+  string_length = (size_t)bytes_rs[3];
 
   if (string_length)
-    memcpy (post_code_string, &bytes_rs[4], string_length);
+    {
+      if (string_length > (size_t)(rs_len - 4))
+        string_length = rs_len - 4;
+      if (string_length > IPMI_OEM_STR_BUFLEN)
+        string_length = IPMI_OEM_STR_BUFLEN;
+      memcpy (post_code_string, &bytes_rs[4], string_length);
+    }
 
   pstdout_printf (state_data->pstate,
 		  "Post Code %02Xh : %s\n",
--- a/ipmi-oem/ipmi-oem-supermicro.c
+++ b/ipmi-oem/ipmi-oem-supermicro.c
@@ -129,7 +129,12 @@
   firmware_hardware_id = bytes_rs[18];
   
   if (rs_len > 19)
-    memcpy (firmware_tag, &bytes_rs[19], rs_len - 19);
+    {
+      size_t tag_len = (size_t)(rs_len - 19);
+      if (tag_len > IPMI_OEM_SUPERMICRO_STRING_MAX)
+        tag_len = IPMI_OEM_SUPERMICRO_STRING_MAX;
+      memcpy (firmware_tag, &bytes_rs[19], tag_len);
+    }
 
   /* assume minor version is BCD, just like in Get Device ID command */
   /* assume sub version is also BCD */ 
--- a/ipmi-oem/ipmi-oem-wistron.c
+++ b/ipmi-oem/ipmi-oem-wistron.c
@@ -3047,6 +3047,7 @@
   char string[IPMI_OEM_WISTRON_PROPRIETARY_STRING_MAX + 1];
   int rs_len;
   int rv = -1;
+  size_t len;
 
   assert (state_data);
   assert (!state_data->prog_data->args->oem_options_count);
@@ -3107,8 +3108,12 @@
       goto cleanup;
     }
 
+  len = (size_t)bytes_rs[3];
+  if (len > (size_t)(rs_len - 4))
+    len = rs_len - 4;
+
   memset (string, '\0', IPMI_OEM_WISTRON_PROPRIETARY_STRING_MAX + 1);
-  memcpy (string, &bytes_rs[4], bytes_rs[3]);
+  memcpy (string, &bytes_rs[4], len);
 
   pstdout_printf (state_data->pstate,
 		  "%s\n",
