greybus: firmware: fix information leak
Add missing sanity checks on get_firmware-request offset and size parameters to fix potential information leaks. This prevents remotely controlled information leaks as the requestor currently controls both the 32-bit firmware-image offset and the amount of data that is returned (up to host-device MTU). Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
81ad699461
commit
98645a9c69
@ -87,6 +87,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
|
||||
{
|
||||
struct gb_connection *connection = op->connection;
|
||||
struct gb_firmware *firmware = connection->private;
|
||||
const struct firmware *fw = firmware->fw;
|
||||
struct gb_firmware_get_firmware_request *firmware_request = op->request->payload;
|
||||
struct gb_firmware_get_firmware_response *firmware_response;
|
||||
struct device *dev = &connection->bundle->dev;
|
||||
@ -99,7 +100,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!firmware->fw) {
|
||||
if (!fw) {
|
||||
dev_err(dev, "%s: firmware not available\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -107,6 +108,12 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
|
||||
offset = le32_to_cpu(firmware_request->offset);
|
||||
size = le32_to_cpu(firmware_request->size);
|
||||
|
||||
if (offset >= fw->size || size > fw->size - offset) {
|
||||
dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n",
|
||||
offset, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size,
|
||||
GFP_KERNEL)) {
|
||||
dev_err(dev, "%s: error allocating response\n", __func__);
|
||||
@ -114,7 +121,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
|
||||
}
|
||||
|
||||
firmware_response = op->response->payload;
|
||||
memcpy(firmware_response->data, firmware->fw->data + offset, size);
|
||||
memcpy(firmware_response->data, fw->data + offset, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user