Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: libstoragemgmt-1.10.1-4.el10 ------ Summary: Stack Buffer Overflow in VPD 0x80 Serial Parsing (`_sg_parse_vpd_80`): attacker-controlled or malformed VPD page length data can overflow a fixed-size caller stack buffer during serial number parsing Requirements to exploit: The attacker must be able to make `libstoragemgmt` process malformed SCSI VPD page `0x80` data through the local disk serial-number query path. In practice, this appears to require control of a local or virtual storage device, or of a storage stack that can return attacker-controlled VPD data. Component affected: `libstoragemgmt-1.10.1-4.el10`, `c_binding/libsg.c`, function `_sg_parse_vpd_80()`; reachable from the local disk serial-number query path Version affected: `libstoragemgmt-1.10.1-4.el10` Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H - 6.2 (MEDIUM) AV:L - The issue is exercised through a local storage-device data path rather than a remote network-exposed interface. AC:L - Once malformed VPD page `0x80` data is supplied, the overflow follows directly from the unchecked length field. PR:L - The attacker needs the ability to present or control the relevant local device context or storage response path. UI:N - No additional user interaction is required after the vulnerable code path is invoked. S:U - The impact is limited to the security scope of the consuming process. C:N - The available evidence does not demonstrate confidentiality impact. I:N - The available evidence does not demonstrate integrity impact. A:H - Stack corruption can crash or destabilize the process performing the serial-number query. Impact: Moderate. The flaw is a real memory-safety issue in a shipped package and can cause process compromise in the form of a stack overwrite, with denial of service as the clearest demonstrated outcome. However, the current evidence supports a local, device-data-dependent trigger rather than an easily exploitable remote condition, and no direct confidentiality or integrity impact has been established. That is more consistent with Red Hat Moderate severity than Important or Critical. Embargo: no Reason: The demonstrated attack path is local and depends on attacker-controlled or malformed storage VPD data. The currently supported impact is primarily process crash or instability, and the issue does not appear to meet the usual threshold for embargoed handling. Acknowledgement: Aisle Research Vulnerability Details: In `_sg_parse_vpd_80()`, the serial number length is derived from the untrusted VPD header field `page_len_be` and then used as the `snprintf()` destination size, without being bounded by the caller-provided destination capacity `serial_num_max_len`. The code checks only that the VPD response stays within `_SG_T10_SPC_VPD_MAX_LEN`, which is a VPD buffer limit, not the size of the destination stack buffer used by the caller. ```c serial_num_len = be16toh(vpd80_header->page_len_be); vpd80_len = serial_num_len + sizeof(struct _sg_t10_vpd83_header); end_p = vpd_data + vpd80_len - 1; if (end_p >= vpd_data + _SG_T10_SPC_VPD_MAX_LEN) { rc = LSM_ERR_LIB_BUG; _lsm_err_msg_set(err_msg, "BUG: Got invalid VPD UNIT SN page response, " "data length exceeded the maximum size of a legal VPD " "page"); goto out; } p = vpd_data + sizeof(struct _sg_t10_vpd83_header); // add extra character to allow for terminating NULL serial_num_len += 1; len = snprintf((char *)serial_num, serial_num_len, "%s", (char *)p); ``` The affected call chain is the local disk serial-number path: `lsm_local_disk_serial_num_get()` -> `_sysfs_serial_num_of_sd_name()` -> `_sysfs_vpd_pg80_data_get()` -> `_sg_parse_vpd_80()`. The available analysis indicates that the caller uses a fixed-size 253-byte stack buffer for the serial number. If `page_len_be` exceeds 252 and the payload is not NUL-terminated early, `snprintf()` may write past that buffer. Based on the current evidence, this is sufficient to establish a stack-based overflow and likely process crash, but it does not by itself establish code execution or data exposure. Steps to reproduce: 1. Build a small harness with AddressSanitizer that calls `_sg_parse_vpd_80()` directly. 2. Allocate `uint8_t vpd_data[_SG_T10_SPC_VPD_MAX_LEN];` and a 253-byte `serial_num` buffer. 3. Set `((struct _sg_t10_vpd80_header *)vpd_data)->page_code = 0x80;`. 4. Set `((struct _sg_t10_vpd80_header *)vpd_data)->page_len_be = htobe16(0x0400);`. 5. Fill the payload region starting at `sizeof(struct _sg_t10_vpd83_header)` with non-zero bytes and place a terminating `'\0'` much later in the buffer. 6. Call `_sg_parse_vpd_80(err_msg, vpd_data, serial_num, 253);`. 7. Run the harness under ASan and observe a stack-buffer-overflow on the `snprintf()` write. Mitigation: Until a fix is available, avoid querying local disk serial numbers from untrusted or attacker-controlled storage devices or virtual storage backends. Treat malformed VPD page `0x80` data as unsupported, and reject or sanitize serial lengths before copying into fixed-size buffers. Proposed Fix: The copy should be bounded by `serial_num_max_len`, not by the untrusted VPD length field. The following minimal patch preserves the current error-on-truncation behavior while removing the overflow condition. ```diff diff --git a/c_binding/libsg.c b/c_binding/libsg.c @@ // add extra character to allow for terminating NULL serial_num_len += 1; len = snprintf((char *)serial_num, serial_num_len, "%s", (char *)p); - if ((uint16_t)len >= serial_num_len) { + /* Never use untrusted VPD length as destination size. */ + len = snprintf((char *)serial_num, serial_num_max_len, "%.*s", + (int)serial_num_len, (char *)p); + + if (len < 0 || (uint16_t)len >= serial_num_max_len) { memset(serial_num, 0, serial_num_max_len); rc = LSM_ERR_LIB_BUG; _lsm_err_msg_set(err_msg, "BUG: VPD UNIT SN was truncated when copied."); } ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use