Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ibmasm: fix OOB reads in command_file_write due to missing size checks

The command_file_write() handler allocates a kernel buffer of exactly
count bytes and copies user data into it, but does not validate the
buffer against the dot command protocol before passing it to
get_dot_command_size() and get_dot_command_timeout().

Since both the allocation size (count) and the header fields (command_size,
data_size) are independently user-controlled, an attacker can cause
get_dot_command_size() to return a value exceeding the allocation,
triggering OOB reads in get_dot_command_timeout() and an out-of-bounds
memcpy_toio() that leaks kernel heap memory to the service processor.

Fix with two guards: reject writes smaller than sizeof(struct
dot_command_header) before allocation, then after copying user data
reject commands where the buffer is smaller than the total size declared
by the header (sizeof(header) + command_size + data_size). This ensures
all subsequent header and payload field accesses stay within the buffer.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tyllis Xu <LivelyCarpet87@gmail.com>
Link: https://patch.msgid.link/20260314165355.548119-1-LivelyCarpet87@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Tyllis Xu and committed by
Greg Kroah-Hartman
0eb09f73 4b6e6ead

+7
+7
drivers/misc/ibmasm/ibmasmfs.c
··· 303 303 return -EINVAL; 304 304 if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE) 305 305 return 0; 306 + if (count < sizeof(struct dot_command_header)) 307 + return -EINVAL; 306 308 if (*offset != 0) 307 309 return 0; 308 310 ··· 319 317 if (copy_from_user(cmd->buffer, ubuff, count)) { 320 318 command_put(cmd); 321 319 return -EFAULT; 320 + } 321 + 322 + if (count < get_dot_command_size(cmd->buffer)) { 323 + command_put(cmd); 324 + return -EINVAL; 322 325 } 323 326 324 327 spin_lock_irqsave(&command_data->sp->lock, flags);