USB: Use BStackOrHeapArray in RegisterNode.
I saw in a KDL stack trace that this function was using over 4KB of stack. As it is called as part of device_manager startup, where there can be pretty deep recursion happening, that seems like a bad idea. Additionally, it did not actually do bounds checking. Now we dynamically allocate an array of sufficient length.
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "usb_private.h"
|
#include "usb_private.h"
|
||||||
|
|
||||||
|
#include <StackOrHeapArray.h>
|
||||||
|
|
||||||
|
|
||||||
Device::Device(Object* parent, int8 hubAddress, uint8 hubPort,
|
Device::Device(Object* parent, int8 hubAddress, uint8 hubPort,
|
||||||
usb_device_descriptor& desc, int8 deviceAddress, usb_speed speed,
|
usb_device_descriptor& desc, int8 deviceAddress, usb_speed speed,
|
||||||
@@ -843,18 +845,24 @@ Device::RegisterNode(device_node *parent)
|
|||||||
if (parent == NULL)
|
if (parent == NULL)
|
||||||
parent = ((Device*)Parent())->Node();
|
parent = ((Device*)Parent())->Node();
|
||||||
|
|
||||||
device_attr attrs[128] = {
|
// determine how many attributes we will need
|
||||||
{ B_DEVICE_BUS, B_STRING_TYPE, { .string = "usb" }},
|
uint32 deviceAttrTotal = 1;
|
||||||
|
for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) {
|
||||||
|
for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) {
|
||||||
|
for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) {
|
||||||
|
deviceAttrTotal += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// location
|
BStackOrHeapArray<device_attr, 16> attrs(deviceAttrTotal + 4 + 5);
|
||||||
{ USB_DEVICE_ID_ITEM, B_UINT32_TYPE, { .ui32 = id }},
|
attrs[0] = { B_DEVICE_BUS, B_STRING_TYPE, { .string = "usb" } };
|
||||||
|
|
||||||
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { .ui32 = B_FIND_MULTIPLE_CHILDREN }},
|
// location
|
||||||
|
attrs[1] = { USB_DEVICE_ID_ITEM, B_UINT32_TYPE, { .ui32 = id } };
|
||||||
|
attrs[2] = { B_DEVICE_FLAGS, B_UINT32_TYPE, { .ui32 = B_FIND_MULTIPLE_CHILDREN } };
|
||||||
|
attrs[3] = { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "USB device" } };
|
||||||
|
|
||||||
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "USB device" }},
|
|
||||||
|
|
||||||
{ NULL }
|
|
||||||
};
|
|
||||||
uint32 attrCount = 4;
|
uint32 attrCount = 4;
|
||||||
|
|
||||||
if (fDeviceDescriptor.vendor_id != 0) {
|
if (fDeviceDescriptor.vendor_id != 0) {
|
||||||
@@ -862,6 +870,7 @@ Device::RegisterNode(device_node *parent)
|
|||||||
attrs[attrCount].type = B_UINT16_TYPE;
|
attrs[attrCount].type = B_UINT16_TYPE;
|
||||||
attrs[attrCount].value.ui16 = fDeviceDescriptor.vendor_id;
|
attrs[attrCount].value.ui16 = fDeviceDescriptor.vendor_id;
|
||||||
attrCount++;
|
attrCount++;
|
||||||
|
|
||||||
attrs[attrCount].name = B_DEVICE_ID;
|
attrs[attrCount].name = B_DEVICE_ID;
|
||||||
attrs[attrCount].type = B_UINT16_TYPE;
|
attrs[attrCount].type = B_UINT16_TYPE;
|
||||||
attrs[attrCount].value.ui16 = fDeviceDescriptor.product_id;
|
attrs[attrCount].value.ui16 = fDeviceDescriptor.product_id;
|
||||||
@@ -875,10 +884,12 @@ Device::RegisterNode(device_node *parent)
|
|||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_class;
|
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_class;
|
||||||
attrCount++;
|
attrCount++;
|
||||||
|
|
||||||
attrs[attrCount].name = USB_DEVICE_SUBCLASS;
|
attrs[attrCount].name = USB_DEVICE_SUBCLASS;
|
||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_subclass;
|
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_subclass;
|
||||||
attrCount++;
|
attrCount++;
|
||||||
|
|
||||||
attrs[attrCount].name = USB_DEVICE_PROTOCOL;
|
attrs[attrCount].name = USB_DEVICE_PROTOCOL;
|
||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_protocol;
|
attrs[attrCount].value.ui8 = fDeviceDescriptor.device_protocol;
|
||||||
@@ -903,14 +914,17 @@ Device::RegisterNode(device_node *parent)
|
|||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
attrs[attrCount].name = USB_DEVICE_CLASS;
|
attrs[attrCount].name = USB_DEVICE_CLASS;
|
||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = descriptor->interface_class;
|
attrs[attrCount].value.ui8 = descriptor->interface_class;
|
||||||
attrCount++;
|
attrCount++;
|
||||||
|
|
||||||
attrs[attrCount].name = USB_DEVICE_SUBCLASS;
|
attrs[attrCount].name = USB_DEVICE_SUBCLASS;
|
||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = descriptor->interface_subclass;
|
attrs[attrCount].value.ui8 = descriptor->interface_subclass;
|
||||||
attrCount++;
|
attrCount++;
|
||||||
|
|
||||||
attrs[attrCount].name = USB_DEVICE_PROTOCOL;
|
attrs[attrCount].name = USB_DEVICE_PROTOCOL;
|
||||||
attrs[attrCount].type = B_UINT8_TYPE;
|
attrs[attrCount].type = B_UINT8_TYPE;
|
||||||
attrs[attrCount].value.ui8 = descriptor->interface_protocol;
|
attrs[attrCount].value.ui8 = descriptor->interface_protocol;
|
||||||
@@ -919,10 +933,14 @@ Device::RegisterNode(device_node *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attrs[attrCount].name = NULL;
|
||||||
|
attrs[attrCount].type = 0;
|
||||||
|
attrs[attrCount].value.string = NULL;
|
||||||
|
attrCount++;
|
||||||
|
|
||||||
device_node* node = NULL;
|
device_node* node = NULL;
|
||||||
if (gDeviceManager->register_node(parent, USB_DEVICE_MODULE_NAME, attrs,
|
if (gDeviceManager->register_node(parent, USB_DEVICE_MODULE_NAME, attrs,
|
||||||
NULL, &node) != B_OK) {
|
NULL, &node) != B_OK) {
|
||||||
TRACE_ERROR("failed to register device node\n");
|
TRACE_ERROR("failed to register device node\n");
|
||||||
} else
|
} else
|
||||||
fNode = node;
|
fNode = node;
|
||||||
|
|||||||
Reference in New Issue
Block a user