Skip to content

Commit a672682

Browse files
LivelyCarpet87gregkh
authored andcommitted
ibmasm: fix OOB reads in command_file_write due to missing size checks
commit 0eb09f7 upstream. 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: 1da177e ("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>
1 parent fc7e9a7 commit a672682

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

drivers/misc/ibmasm/ibmasmfs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ static ssize_t command_file_write(struct file *file, const char __user *ubuff, s
303303
return -EINVAL;
304304
if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
305305
return 0;
306+
if (count < sizeof(struct dot_command_header))
307+
return -EINVAL;
306308
if (*offset != 0)
307309
return 0;
308310

@@ -319,6 +321,11 @@ static ssize_t command_file_write(struct file *file, const char __user *ubuff, s
319321
return -EFAULT;
320322
}
321323

324+
if (count < get_dot_command_size(cmd->buffer)) {
325+
command_put(cmd);
326+
return -EINVAL;
327+
}
328+
322329
spin_lock_irqsave(&command_data->sp->lock, flags);
323330
if (command_data->command) {
324331
spin_unlock_irqrestore(&command_data->sp->lock, flags);

0 commit comments

Comments
 (0)