usb_disk: Handle user buffer-to-partial buffer copies correctly.
Discovered by an SMAP violation triggered by running "writembr" on a USB drive.
This commit is contained in:
parent
6b0251e1bd
commit
c61fa718f2
|
@ -16,6 +16,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
#include <fs/devfs.h>
|
#include <fs/devfs.h>
|
||||||
|
|
||||||
#include "scsi_sense.h"
|
#include "scsi_sense.h"
|
||||||
|
@ -2027,6 +2028,9 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length)
|
||||||
result = usb_disk_prepare_partial_buffer(lun, position, *length,
|
result = usb_disk_prepare_partial_buffer(lun, position, *length,
|
||||||
partialBuffer, blockBuffer, blockPosition, blockCount);
|
partialBuffer, blockBuffer, blockPosition, blockCount);
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
|
if (IS_USER_ADDRESS(buffer))
|
||||||
|
result = user_memcpy(buffer, partialBuffer, *length);
|
||||||
|
else
|
||||||
memcpy(buffer, partialBuffer, *length);
|
memcpy(buffer, partialBuffer, *length);
|
||||||
free(blockBuffer);
|
free(blockBuffer);
|
||||||
}
|
}
|
||||||
|
@ -2075,7 +2079,12 @@ usb_disk_write(void *cookie, off_t position, const void *buffer,
|
||||||
result = usb_disk_prepare_partial_buffer(lun, position, *length,
|
result = usb_disk_prepare_partial_buffer(lun, position, *length,
|
||||||
partialBuffer, blockBuffer, blockPosition, blockCount);
|
partialBuffer, blockBuffer, blockPosition, blockCount);
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
|
if (IS_USER_ADDRESS(buffer))
|
||||||
|
result = user_memcpy(partialBuffer, buffer, *length);
|
||||||
|
else
|
||||||
memcpy(partialBuffer, buffer, *length);
|
memcpy(partialBuffer, buffer, *length);
|
||||||
|
}
|
||||||
|
if (result == B_OK) {
|
||||||
size_t blockLength = blockCount * lun->block_size;
|
size_t blockLength = blockCount * lun->block_size;
|
||||||
result = usb_disk_block_write(lun, blockPosition, blockCount,
|
result = usb_disk_block_write(lun, blockPosition, blockCount,
|
||||||
blockBuffer, &blockLength);
|
blockBuffer, &blockLength);
|
||||||
|
|
Loading…
Reference in New Issue