usb_hid: use user_memcpy to read/write the user buffers.

also check buffer addresses.
This commit is contained in:
Jérôme Duval
2018-02-08 13:31:15 +01:00
parent 2539550c6e
commit f1549b1611
2 changed files with 42 additions and 16 deletions
@@ -369,6 +369,9 @@ KeyboardProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
continue; continue;
} }
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
// process what is in the ring_buffer, it could be written // process what is in the ring_buffer, it could be written
// there because we handled an interrupt transfer or because // there because we handled an interrupt transfer or because
// we wrote the current repeat key // we wrote the current repeat key
@@ -379,16 +382,21 @@ KeyboardProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
case KB_SET_LEDS: case KB_SET_LEDS:
{ {
uint8 ledData[4]; uint8 ledData[4];
if (user_memcpy(ledData, buffer, sizeof(ledData)) != B_OK) if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(ledData, buffer, sizeof(ledData)) != B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
}
return _SetLEDs(ledData); return _SetLEDs(ledData);
} }
case KB_SET_KEY_REPEAT_RATE: case KB_SET_KEY_REPEAT_RATE:
{ {
int32 repeatRate; int32 repeatRate;
if (user_memcpy(&repeatRate, buffer, sizeof(repeatRate)) != B_OK) if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(&repeatRate, buffer, sizeof(repeatRate))
!= B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
}
if (repeatRate == 0 || repeatRate > 1000000) if (repeatRate == 0 || repeatRate > 1000000)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -400,21 +408,28 @@ KeyboardProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
case KB_GET_KEY_REPEAT_RATE: case KB_GET_KEY_REPEAT_RATE:
{ {
int32 repeatRate = 10000000 / fRepeatRate; int32 repeatRate = 10000000 / fRepeatRate;
if (user_memcpy(buffer, &repeatRate, sizeof(repeatRate)) != B_OK) if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(buffer, &repeatRate, sizeof(repeatRate))
!= B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
} }
case KB_SET_KEY_REPEAT_DELAY: case KB_SET_KEY_REPEAT_DELAY:
if (user_memcpy(&fRepeatDelay, buffer, sizeof(fRepeatDelay)) if (!IS_USER_ADDRESS(buffer)
!= B_OK) || user_memcpy(&fRepeatDelay, buffer, sizeof(fRepeatDelay))
!= B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
case KB_GET_KEY_REPEAT_DELAY: case KB_GET_KEY_REPEAT_DELAY:
if (user_memcpy(buffer, &fRepeatDelay, sizeof(fRepeatDelay)) if (!IS_USER_ADDRESS(buffer)
!= B_OK) || user_memcpy(buffer, &fRepeatDelay, sizeof(fRepeatDelay))
!= B_OK) {
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
case KB_SET_DEBUG_READER: case KB_SET_DEBUG_READER:
@@ -19,6 +19,7 @@
#include <string.h> #include <string.h>
#include <usb/USB_hid.h> #include <usb/USB_hid.h>
#include <kernel.h>
#include <keyboard_mouse_driver.h> #include <keyboard_mouse_driver.h>
@@ -132,9 +133,18 @@ MouseProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
return B_BUFFER_OVERFLOW; return B_BUFFER_OVERFLOW;
while (true) { while (true) {
status_t result = _ReadReport(buffer, cookie); mouse_movement movement;
if (result != B_INTERRUPTED) status_t result = _ReadReport(&movement, cookie);
return result; if (result == B_INTERRUPTED)
continue;
if (!IS_USER_ADDRESS(buffer)
|| user_memcpy(buffer, &movement, sizeof(movement))
!= B_OK) {
return B_BAD_ADDRESS;
}
return result;
} }
} }
@@ -148,12 +158,13 @@ MouseProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
} }
case MS_SET_CLICKSPEED: case MS_SET_CLICKSPEED:
#ifdef __HAIKU__ if (!IS_USER_ADDRESS(buffer)
return user_memcpy(&fClickSpeed, buffer, sizeof(bigtime_t)); || user_memcpy(&fClickSpeed, buffer, sizeof(bigtime_t))
#else != B_OK) {
fClickSpeed = *(bigtime_t *)buffer; return B_BAD_ADDRESS;
return B_OK; }
#endif
return B_OK;
} }
return B_ERROR; return B_ERROR;