mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
firewire: cdev: tcodes input validation
The behaviour of fw-transaction.c::fw_send_request is ill-defined for any other tcodes than read/ write/ lock request tcodes. Therefore prevent requests with wrong tcodes from entering the transaction layer. Maybe fw_send_request should check them itself, but I am not inclined to change it and fw_fill_request from void-valued functions to ones which return error codes and pass those up. Besides, maybe fw_send_request is going to support one more tcode than ioctl_send_request in the future (TCODE_STREAM_DATA). Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
parent
bf8e3355ec
commit
1f3125af8e
1 changed files with 25 additions and 2 deletions
|
@ -398,6 +398,7 @@ static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
struct fw_device *device = client->device;
|
struct fw_device *device = client->device;
|
||||||
struct fw_cdev_send_request *request = buffer;
|
struct fw_cdev_send_request *request = buffer;
|
||||||
struct response *response;
|
struct response *response;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* What is the biggest size we'll accept, really? */
|
/* What is the biggest size we'll accept, really? */
|
||||||
if (request->length > 4096)
|
if (request->length > 4096)
|
||||||
|
@ -414,8 +415,26 @@ static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
if (request->data &&
|
if (request->data &&
|
||||||
copy_from_user(response->response.data,
|
copy_from_user(response->response.data,
|
||||||
u64_to_uptr(request->data), request->length)) {
|
u64_to_uptr(request->data), request->length)) {
|
||||||
kfree(response);
|
ret = -EFAULT;
|
||||||
return -EFAULT;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (request->tcode) {
|
||||||
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
|
case TCODE_WRITE_BLOCK_REQUEST:
|
||||||
|
case TCODE_READ_QUADLET_REQUEST:
|
||||||
|
case TCODE_READ_BLOCK_REQUEST:
|
||||||
|
case TCODE_LOCK_MASK_SWAP:
|
||||||
|
case TCODE_LOCK_COMPARE_SWAP:
|
||||||
|
case TCODE_LOCK_FETCH_ADD:
|
||||||
|
case TCODE_LOCK_LITTLE_ADD:
|
||||||
|
case TCODE_LOCK_BOUNDED_ADD:
|
||||||
|
case TCODE_LOCK_WRAP_ADD:
|
||||||
|
case TCODE_LOCK_VENDOR_DEPENDENT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
response->resource.release = release_transaction;
|
response->resource.release = release_transaction;
|
||||||
|
@ -434,6 +453,10 @@ static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
return sizeof(request) + request->length;
|
return sizeof(request) + request->length;
|
||||||
else
|
else
|
||||||
return sizeof(request);
|
return sizeof(request);
|
||||||
|
err:
|
||||||
|
kfree(response);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct address_handler {
|
struct address_handler {
|
||||||
|
|
Loading…
Add table
Reference in a new issue