From f156915125a82b2789756febed5ea3ce014590e9 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Fri, 20 Mar 2026 13:41:09 +0100 Subject: [PATCH] Handle the case of malformed IOCTL answer for disk descriptor --- HISTORY | 4 ++++ cmdline/mingw.c | 45 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/HISTORY b/HISTORY index c0ce889c..812cc7bf 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,10 @@ SnapRAID HISTORY ================ +14.0rc3e 22/03/2026 +=================== + * Fixed reading of serial number in Windows + 14.0rc3d 22/03/2026 =================== * Fixed data race on the new RELOCATED flag diff --git a/cmdline/mingw.c b/cmdline/mingw.c index 3780d07d..5856e0b2 100644 --- a/cmdline/mingw.c +++ b/cmdline/mingw.c @@ -2537,6 +2537,40 @@ retry: return 0; } +static int serial_descriptor(PSTORAGE_DEVICE_DESCRIPTOR descriptor, size_t size, char* output, size_t output_size) +{ + if (descriptor->SerialNumberOffset == 0 + || descriptor->SerialNumberOffset == (DWORD)-1 + || descriptor->SerialNumberOffset >= size) + return -1; + + const char* raw = (const char*)descriptor + descriptor->SerialNumberOffset; + size_t len = 0; + + /* find the length, not assuming a 0 ending */ + while (descriptor->SerialNumberOffset + len < size && raw[len] != 0) + ++len; + + if (len < 6) /* a serial cannot be so short */ + return -1; + + if (len + 1 > output_size) + return -1; + + /* all must be printable */ + for (size_t i = 0; i < len; ++i) { + if (!isprint((unsigned char)raw[i])) + return -1; + } + + memcpy(output, raw, len); + output[len] = 0; + + strtrim(output); + + return 0; +} + static void devattr_property(HANDLE h, char* serial, char* model, char* inter) { STORAGE_PROPERTY_QUERY query = { 0 }; @@ -2568,15 +2602,14 @@ static void devattr_property(HANDLE h, char* serial, char* model, char* inter) strtrim(model); } - if (serial && *serial == 0 && desc->SerialNumberOffset) { + if (serial && *serial == 0) { /* - * This is the RAW serial, maybe HEX encoded, maybe BYTES SWAPPED - * but we don't care because we just need any identifier + * This is the RAW serial, maybe HEX encoded, maybe BYTES SWAPPED, + * but we don't care because we just need any identifier. * - * If smartctl was not able to read it, we now accept anything + * If smartctl was not able to read it, we now accept anything. */ - snprintf(serial, SMART_MAX, "%s", (char*)(buffer + desc->SerialNumberOffset)); - strtrim(serial); + serial_descriptor(desc, bytes, serial, SMART_MAX); } #define BusTypeVirtual 0x0E