mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Validate the product/model returned by the Windows driver
This commit is contained in:
parent
c79f82bc99
commit
02413b756c
1 changed files with 62 additions and 13 deletions
|
|
@ -983,15 +983,45 @@ static int serial_descriptor(PSTORAGE_DEVICE_DESCRIPTOR descriptor, size_t 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 */
|
||||
const char* end = memchr(raw, 0, size - descriptor->SerialNumberOffset);
|
||||
if (!end)
|
||||
return -1;
|
||||
|
||||
size_t len = end - raw;
|
||||
if (len + 1 > output_size)
|
||||
return -1;
|
||||
|
||||
/* a serial cannot be too short */
|
||||
if (len < 6)
|
||||
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 int product_descriptor(PSTORAGE_DEVICE_DESCRIPTOR descriptor, size_t size, char* output, size_t output_size)
|
||||
{
|
||||
if (descriptor->ProductIdOffset == 0
|
||||
|| descriptor->ProductIdOffset == (DWORD)-1
|
||||
|| descriptor->ProductIdOffset >= size)
|
||||
return -1;
|
||||
|
||||
const char* raw = (const char*)descriptor + descriptor->ProductIdOffset;
|
||||
const char* end = memchr(raw, 0, size - descriptor->ProductIdOffset);
|
||||
if (!end)
|
||||
return -1;
|
||||
|
||||
size_t len = end - raw;
|
||||
if (len + 1 > output_size)
|
||||
return -1;
|
||||
|
||||
|
|
@ -1013,13 +1043,15 @@ static void devattr_property(HANDLE h, char* serial, char* model, char* inter)
|
|||
{
|
||||
STORAGE_PROPERTY_QUERY query = { 0 };
|
||||
STORAGE_DESCRIPTOR_HEADER header = { 0 };
|
||||
STORAGE_DEVICE_DESCRIPTOR* desc;
|
||||
size_t descriptor_size;
|
||||
DWORD bytes;
|
||||
|
||||
query.PropertyId = StorageDeviceProperty;
|
||||
query.QueryType = PropertyStandardQuery;
|
||||
if (!DeviceIoControl(h, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &header, sizeof(header), &bytes, 0))
|
||||
return;
|
||||
if (header.Size == 0)
|
||||
if (header.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))
|
||||
return;
|
||||
|
||||
/* allocate buffer and query full descriptor */
|
||||
|
|
@ -1032,12 +1064,29 @@ static void devattr_property(HANDLE h, char* serial, char* model, char* inter)
|
|||
return;
|
||||
}
|
||||
|
||||
STORAGE_DEVICE_DESCRIPTOR* desc = (STORAGE_DEVICE_DESCRIPTOR*)buffer;
|
||||
/*
|
||||
* Do not trust the descriptor size or offsets returned by a storage driver.
|
||||
* DeviceIoControl() may return fewer bytes than requested, and strings in
|
||||
* the descriptor are only offsets into the returned byte range.
|
||||
*/
|
||||
if (bytes < sizeof(STORAGE_DEVICE_DESCRIPTOR)) {
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
desc = (STORAGE_DEVICE_DESCRIPTOR*)buffer;
|
||||
descriptor_size = bytes;
|
||||
if (descriptor_size > header.Size)
|
||||
descriptor_size = header.Size;
|
||||
if (desc->Size < sizeof(STORAGE_DEVICE_DESCRIPTOR) || desc->Size > descriptor_size) {
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
descriptor_size = desc->Size;
|
||||
|
||||
/* extract strings (offsets are from start of descriptor) */
|
||||
if (model && *model == 0 && desc->ProductIdOffset) {
|
||||
snprintf(model, SMART_MAX, "%s", (char*)(buffer + desc->ProductIdOffset));
|
||||
strtrim(model);
|
||||
if (model && *model == 0) {
|
||||
product_descriptor(desc, descriptor_size, model, SMART_MAX);
|
||||
}
|
||||
|
||||
if (serial && *serial == 0) {
|
||||
|
|
@ -1047,7 +1096,7 @@ static void devattr_property(HANDLE h, char* serial, char* model, char* inter)
|
|||
*
|
||||
* If smartctl was not able to read it, we now accept anything.
|
||||
*/
|
||||
serial_descriptor(desc, bytes, serial, SMART_MAX);
|
||||
serial_descriptor(desc, descriptor_size, serial, SMART_MAX);
|
||||
}
|
||||
|
||||
#define BusTypeVirtual 0x0E
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue