From 04ff1cfaef5441437c07d65577634cd2f4d7891e Mon Sep 17 00:00:00 2001 From: X512 Date: Sat, 18 Apr 2020 04:02:42 +0900 Subject: [PATCH] i2c bus_raw: fix passing cmdBuffer, handle large buffer size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia2965d465899d087f0cbf8f7b07a7a326ed305db Reviewed-on: https://review.haiku-os.org/c/haiku/+/2496 Reviewed-by: Jérôme Duval --- .../kernel/bus_managers/i2c/bus_raw.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/i2c/bus_raw.cpp b/src/add-ons/kernel/bus_managers/i2c/bus_raw.cpp index dfe3af8674..885d4edc8f 100644 --- a/src/add-ons/kernel/bus_managers/i2c/bus_raw.cpp +++ b/src/add-ons/kernel/bus_managers/i2c/bus_raw.cpp @@ -6,6 +6,8 @@ #include "I2CPrivate.h" +#include + static status_t i2c_bus_raw_init(void* driverCookie, void **_cookie) @@ -64,14 +66,23 @@ i2c_bus_raw_control(void *_cookie, uint32 op, void *data, size_t length) case I2CEXEC: { i2c_ioctl_exec exec; - uint8 cmdBuffer[32]; - uint8 buffer[32]; const void* userCmdBuffer = NULL; void* userBuffer = NULL; if (user_memcpy(&exec, data, sizeof(i2c_ioctl_exec)) != B_OK) return B_BAD_ADDRESS; + + if (exec.cmdBuffer == NULL) + exec.cmdLength = 0; + if (exec.buffer == NULL) + exec.bufferLength = 0; + BStackOrHeapArray cmdBuffer(exec.cmdLength); + BStackOrHeapArray buffer(exec.bufferLength); + if (!cmdBuffer.IsValid() || !buffer.IsValid()) + return B_NO_MEMORY; + if (exec.cmdBuffer != NULL) { - if (user_memcpy(cmdBuffer, exec.cmdBuffer, exec.cmdLength) + if (!IS_USER_ADDRESS(exec.cmdBuffer) + || user_memcpy(cmdBuffer, exec.cmdBuffer, exec.cmdLength) != B_OK) { return B_BAD_ADDRESS; } @@ -79,7 +90,8 @@ i2c_bus_raw_control(void *_cookie, uint32 op, void *data, size_t length) exec.cmdBuffer = cmdBuffer; } if (exec.buffer != NULL) { - if (user_memcpy(buffer, exec.buffer, exec.bufferLength) + if (!IS_USER_ADDRESS(exec.buffer) + || user_memcpy(buffer, exec.buffer, exec.bufferLength) != B_OK) { return B_BAD_ADDRESS; } @@ -92,7 +104,7 @@ i2c_bus_raw_control(void *_cookie, uint32 op, void *data, size_t length) return status; status = bus->ExecCommand(exec.op, exec.addr, - &exec.cmdBuffer, exec.cmdLength, exec.buffer, + exec.cmdBuffer, exec.cmdLength, exec.buffer, exec.bufferLength); bus->ReleaseBus();