From owner-freebsd-arch@freebsd.org Tue Aug 13 19:40:25 2019 Return-Path: Delivered-To: freebsd-arch@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 19CEABA5A5 for ; Tue, 13 Aug 2019 19:40:25 +0000 (UTC) (envelope-from neerajpal09@gmail.com) Received: from mail-ot1-x32c.google.com (mail-ot1-x32c.google.com [IPv6:2607:f8b0:4864:20::32c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 467NNS1wpkz4JBK for ; Tue, 13 Aug 2019 19:40:23 +0000 (UTC) (envelope-from neerajpal09@gmail.com) Received: by mail-ot1-x32c.google.com with SMTP id g17so25829454otl.2 for ; Tue, 13 Aug 2019 12:40:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=9EDkJWM/QLa8zwZrQJrgpug9OAr9B/Ke9HfKE4K4STQ=; b=EUetp50PIkDCJFRxjfQeSWix4HrX/fmy+7l44PDIYAvofHmAhq6VfO68WBryaQNQIH 0XsP2h7/7lJu3eVYVxFWuW2JVunVRyq18B0eiX4nNE4L+25UCpGevUzt5kS9YlequOlD /rJv/XQLx49agyFQ7jkik9vPIFtfLNqoOVs+ZE16OmqfZx9h4iFVFu04TZ9lR3fdb1dC dvWZXSNrWNiQUKX28HS5rezK+0SAIJDGjpZRGzjDj7OXLhug1cx5/DXSG5OywfowOvlk CNBZ8zmN6ZLgXn5MxRUn9BaXJqWTXvqZUJeK3oxJM5PNNqSA1B4J11UEvMWq1SS3PfVI O6vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=9EDkJWM/QLa8zwZrQJrgpug9OAr9B/Ke9HfKE4K4STQ=; b=th+oKhlh0O/t+ZknYC/SQGQsBlQYVRODp2iO25bWn/o8ARdRw3IPEGdhUmEgTtevLy MVu85r0JADo3nrNJzgd0O7VOSEfzOvqHTxwfqci3dTdPo5kPoIBh8fgHYOUpRZkF1LZT Xcaw5rRJvbN9t/IZZg4YFy2/MjqeTd8OfA4r+5yal5A78gQW0gu/1tliab8Vv/300ieo rDIHWdzv2PoEch5ytzLllfBTECtcEF8boQgMFe1XZWogsJbbUkpoh5MhaoLlu8gCgUsb 3qjId4ZJ8wzuLYyT0H4w/iEcrutfMSBUuZKZcIGUR1LqW9yavZPs3gq1+T22XtmeNkfa x+Ow== X-Gm-Message-State: APjAAAXWRuJaUZ7taEBPmRv50jrlCXXblDEKe4QCQRL4n/Kd1fUpZNHD b5wLYMJB7A3RI8zS1iRGBdxt1BgVVU6uRFdpBPT0cQk85lQ= X-Google-Smtp-Source: APXvYqzhwdJoEzEXrIoJfw7UhNw1xnM7KL6fZC5EpQQY0zRStbrMFwWTTuH5Ksj9CYzmH6Km22b0a3HERdxqqEcXr5c= X-Received: by 2002:a9d:7dc6:: with SMTP id k6mr14233955otn.99.1565725222262; Tue, 13 Aug 2019 12:40:22 -0700 (PDT) MIME-Version: 1.0 From: Neeraj Pal Date: Wed, 14 Aug 2019 01:10:10 +0530 Message-ID: Subject: Regarding the bug in FreeBSD kernel driver(s) To: freebsd-arch@freebsd.org X-Rspamd-Queue-Id: 467NNS1wpkz4JBK X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=gmail.com header.s=20161025 header.b=EUetp50P; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (mx1.freebsd.org: domain of neerajpal09@gmail.com designates 2607:f8b0:4864:20::32c as permitted sender) smtp.mailfrom=neerajpal09@gmail.com X-Spamd-Result: default: False [-3.00 / 15.00]; R_SPF_ALLOW(-0.20)[+ip6:2607:f8b0:4000::/36]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_NONE(0.00)[]; URI_COUNT_ODD(1.00)[15]; DKIM_TRACE(0.00)[gmail.com:+]; DMARC_POLICY_ALLOW(-0.50)[gmail.com,none]; NEURAL_HAM_SHORT(-1.00)[-0.997,0]; FROM_EQ_ENVFROM(0.00)[]; IP_SCORE(0.00)[ip: (-9.07), ipnet: 2607:f8b0::/32(-2.97), asn: 15169(-2.39), country: US(-0.05)]; MIME_TRACE(0.00)[0:+,1:+,2:~]; FREEMAIL_ENVFROM(0.00)[gmail.com]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US]; DWL_DNSWL_NONE(0.00)[gmail.com.dwl.dnswl.org : 127.0.5.0]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; R_DKIM_ALLOW(-0.20)[gmail.com:s=20161025]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-arch@freebsd.org]; IP_SCORE_FREEMAIL(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; RCVD_IN_DNSWL_NONE(0.00)[c.2.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.4.6.8.4.0.b.8.f.7.0.6.2.list.dnswl.org : 127.0.5.0]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[] Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Aug 2019 19:40:25 -0000 Hi there, After discussing the issue with the security-team, I have posted it publicly. Please find the bug information given below with workaround diff: I have observed the "NULL pointer dereference" bug inside the FreeBSD kernel driver code due to which kernel gets in panic (or DOS) mode and then it has to reboot. Actually, this vulnerability resides in lots of kernel drivers like "uhub0", "ubt0", "umass0", "run0", "uhid0" etc. I have tested and observed the panic for following kernel drivers: - usb, - umass (storage), - ubt(bluetooth), - run0(wifi), - uhid Please find the PoC in the link: https://www.dropbox.com/s/hd1c0a518nrw749/crash_poc_info.tar.gz?dl=0 I have observed that the devices which are using the structure "usb_attach_arg" with function (or api) device_get_ivars(9) as mentioned below: "struct usb_attach_arg *uaa = device_get_ivars(dev)" are prone to "NULL Pointer Dereference" vulnerability as there is no check for the same and the API device_get_ivars(9) is returning NULL. There are still lots of drivers which are lacking this NULL pointer dereference check but due to unavailability of devices I am not able to test the drivers. However, I am sure about others also. I have tested the following FreeBSD kernel versions: - FreeBSD 13-CURRENT, amd64 - FreeBSD 12-RELEASE, amd64 - FreeBSD 12-STABLE, amd64 [Problem Description] function (or API) device_get_ivars(9) from the file "/usr/src/sys/kern/subr_bus.c" returns a NULL pointer, which get assigned to *uaa structure object (function "uhub_probe" from file "/usr/src/sys/dev/usb/usb_bus.c"), then, after that there is a if-else condition which is checking the usb_mode from that structure and there panic occurs due to dereferencing the NULL pointer Same valid for other kernel drivers. [Background] devctl disable device: it is expected to disable the given device, and devctl enable device: it is supposed to enable the given disabled device. Panic occurs here, after enabling the already disabled device (but only with usb related drivers) [Impact] Puts FreeBSD OS/Kernel in panic mode and then to operate it, a reboot is required. [Privilege] Root privilege is required. [Reproducibility] Reproducibility is 100% [Workaround/Patch] Please find the attached patch for the file "usb_hub.c", "ng_ubt.c", "if_run.c", "umass.c" and "uhid.c" After appyling the patch, it first returns the "ENXIO" as mentioned in the patch code then later invocation returns "EBUSY" as device is enabled, which can be verified by disabling it again. diff -ruN freebsd_orig/sys/dev/usb/input/uhid.c freebsd_13/sys/dev/usb/input/uhid.c --- freebsd_orig/sys/dev/usb/input/uhid.c 2019-08-05 09:46:11.170388578 +0530 +++ freebsd_13/sys/dev/usb/input/uhid.c 2019-08-05 10:28:45.305146412 +0530 @@ -677,6 +677,9 @@ int error; void *buf; uint16_t len; + + if (uaa == NULL) + return (ENXIO); DPRINTFN(11, "\n"); diff -ruN freebsd_orig/sys/dev/usb/storage/umass.c freebsd_13/sys/dev/usb/storage/umass.c --- freebsd_orig/sys/dev/usb/storage/umass.c 2019-08-05 10:13:33.378982245 +0530 +++ freebsd_13/sys/dev/usb/storage/umass.c 2019-08-05 09:36:58.339765496 +0530 @@ -872,6 +872,9 @@ struct usb_attach_arg *uaa = device_get_ivars(dev); struct umass_probe_proto temp; + if (uaa == NULL) + return (ENXIO); + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } diff -ruN freebsd_orig/sys/dev/usb/usb_hub.c freebsd_13/sys/dev/usb/usb_hub.c --- freebsd_orig/sys/dev/usb/usb_hub.c 2019-08-05 10:25:57.276874204 +0530 +++ freebsd_13/sys/dev/usb/usb_hub.c 2019-08-05 08:18:08.537617812 +0530 @@ -1111,6 +1111,9 @@ { struct usb_attach_arg *uaa = device_get_ivars(dev); + if (uaa == NULL) + return (ENXIO); + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); diff -ruN freebsd_orig/sys/dev/usb/wlan/if_run.c freebsd_13/sys/dev/usb/wlan/if_run.c --- freebsd_orig/sys/dev/usb/wlan/if_run.c 2019-08-05 10:13:33.398982487 +0530 +++ freebsd_13/sys/dev/usb/wlan/if_run.c 2019-08-05 09:36:08.982716789 +0530 @@ -720,6 +720,8 @@ { struct usb_attach_arg *uaa = device_get_ivars(self); + if (uaa == NULL) + return (ENXIO); if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != 0) diff -ruN freebsd_orig/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c freebsd_13/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c --- freebsd_orig/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c 2019-08-05 10:13:33.318981516 +0530 +++ freebsd_13/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c 2019-08-05 09:33:46.941575792 +0530 @@ -513,6 +513,9 @@ struct usb_attach_arg *uaa = device_get_ivars(dev); int error; + if (uaa == NULL) + return (ENXIO); + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); I have manually applied necessary checks for this bug to 5 device driver code (names are mentioned above) I have also tried to directly check for "NULL pointer" in the function "device_get_ivars(dev)" but it is returning directly to the structure as mentioned above but still a check is required to be at driver code for structure pointer, that is, *uaa. So, it wasn't working. Now, either we have to manually patch every driver files which are using the above structure with function "device_get_ivars(dev)" or we have to come up with the one line solution for all drivers. [PoC/Log File/binary] Please find the attached tar file in the link ( https://www.dropbox.com/s/hd1c0a518nrw749/crash_poc_info.tar.gz?dl=0) for PoC code, Log Files and PoC binary [Steps to Reproduce] - untar the file "crash_poc_info.tar.gz" - directly load binary from the directory "crash_poc/" or "make" it then load it - usage: ./crash_poc_bin -- For example: ./crash_bin_poc uhub0 or ./crash_bin_poc ubt0 [Attached Files] - Log crash info: "crash_13-current_info/" - PoC src and binary: "crash_poc_codeWith_binary/" - patch: "patch_info/" [Actual results] Panic Log as follows: freebsd dumped core - see ./vmcore.0 Sat Aug 3 17:31:43 UTC 2019 FreeBSD freebsd 13.0-CURRENT FreeBSD 13.0-CURRENT r350103 GENERIC amd64 panic: page fault GNU gdb (GDB) 8.3 [GDB v8.3 for FreeBSD] Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-portbld-freebsd13.0". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /boot/kernel/kernel... Reading symbols from /usr/lib/debug//boot/kernel/kernel.debug... Unread portion of the kernel message buffer: Fatal trap 12: page fault while in kernel mode cpuid = 3; apic id = 03 fault virtual address = 0x38 fault code = supervisor read data, page not present instruction pointer = 0x20:0xffffffff80a0ace1 stack pointer = 0x28:0xfffffe0017f97510 frame pointer = 0x28:0xfffffe0017f97510 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 1005 (devctl) trap number = 12 panic: page fault cpuid = 3 time = 1564812037 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0017f971d0 vpanic() at vpanic+0x19d/frame 0xfffffe0017f97220 panic() at panic+0x43/frame 0xfffffe0017f97280 trap_fatal() at trap_fatal+0x39c/frame 0xfffffe0017f972e0 trap_pfault() at trap_pfault+0x62/frame 0xfffffe0017f97330 trap() at trap+0x2b4/frame 0xfffffe0017f97440 calltrap() at calltrap+0x8/frame 0xfffffe0017f97440 --- trap 0xc, rip = 0xffffffff80a0ace1, rsp = 0xfffffe0017f97510, rbp = 0xfffffe0017f97510 --- uhub_probe() at uhub_probe+0x11/frame 0xfffffe0017f97510 device_probe_child() at device_probe_child+0x194/frame 0xfffffe0017f97570 device_probe() at device_probe+0x98/frame 0xfffffe0017f975a0 device_probe_and_attach() at device_probe_and_attach+0x32/frame 0xfffffe0017f975d0 devctl2_ioctl() at devctl2_ioctl+0x5e2/frame 0xfffffe0017f976a0 devfs_ioctl() at devfs_ioctl+0xca/frame 0xfffffe0017f976f0 VOP_IOCTL_APV() at VOP_IOCTL_APV+0x63/frame 0xfffffe0017f97710 vn_ioctl() at vn_ioctl+0x13d/frame 0xfffffe0017f97820 devfs_ioctl_f() at devfs_ioctl_f+0x1f/frame 0xfffffe0017f97840 kern_ioctl() at kern_ioctl+0x28a/frame 0xfffffe0017f978b0 sys_ioctl() at sys_ioctl+0x15d/frame 0xfffffe0017f97980 amd64_syscall() at amd64_syscall+0x2bb/frame 0xfffffe0017f97ab0 fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe0017f97ab0 --- syscall (54, FreeBSD ELF64, sys_ioctl), rip = 0x80041a31a, rsp = 0x7fffffffea38, rbp = 0x7fffffffeaf0 --- KDB: enter: panic __curthread () at /usr/src/sys/amd64/include/pcpu.h:246 warning: Source file is more recent than executable. 246 __asm("movq %%gs:%P1,%0" : "=r" (td) : "n" (OFFSETOF_CURTHREAD)); (kgdb) #0 __curthread () at /usr/src/sys/amd64/include/pcpu.h:246 #1 doadump (textdump=0) at /usr/src/sys/kern/kern_shutdown.c:392 #2 0xffffffff8049d27b in db_dump (dummy=, dummy2=, dummy3=, dummy4=) at /usr/src/sys/ddb/db_command.c:575 #3 0xffffffff8049d049 in db_command (last_cmdp=, cmd_table=, dopager=1) at /usr/src/sys/ddb/db_command.c:482 #4 0xffffffff8049cdc4 in db_command_loop () at /usr/src/sys/ddb/db_command.c:535 #5 0xffffffff8049ff6f in db_trap (type=, code=) at /usr/src/sys/ddb/db_main.c:252 #6 0xffffffff80c1522c in kdb_trap (type=3, code=0, tf=) at /usr/src/sys/kern/subr_kdb.c:692 #7 0xffffffff81099ba1 in trap (frame=0xfffffe0017f97100) at /usr/src/sys/amd64/amd64/trap.c:621 #8 #9 kdb_enter (why=0xffffffff8132cf49 "panic", msg=) at /usr/src/sys/kern/subr_kdb.c:479 #10 0xffffffff80bcad6a in vpanic (fmt=, ap=) at /usr/src/sys/kern/kern_shutdown.c:894 #11 0xffffffff80bcaae3 in panic ( fmt=0xffffffff81e88898 "\233\036/\201\377\377\377\377") at /usr/src/sys/kern/kern_shutdown.c:832 #12 0xffffffff81099ffc in trap_fatal (frame=0xfffffe0017f97450, eva=56) at /usr/src/sys/amd64/amd64/trap.c:943 #13 0xffffffff8109a062 in trap_pfault (frame=0xfffffe0017f97450, usermode=) at /usr/src/sys/amd64/amd64/trap.c:767 #14 0xffffffff81099644 in trap (frame=0xfffffe0017f97450) at /usr/src/sys/amd64/amd64/trap.c:443 #15 #16 uhub_probe (dev=) at /usr/src/sys/dev/usb/usb_hub.c:1114 #17 0xffffffff80c02574 in DEVICE_PROBE (dev=) at ./device_if.h:115 #18 device_probe_child (dev=0xfffff80003242b00, child=0xfffff800031ff400) at /usr/src/sys/kern/subr_bus.c:2150 #19 0xffffffff80c03388 in device_probe (dev=0xfffff800031ff400) at /usr/src/sys/kern/subr_bus.c:2897 #20 0xffffffff80c03442 in device_probe_and_attach (dev=0xfffff800031ff400) at /usr/src/sys/kern/subr_bus.c:2921 #21 0xffffffff80c08f22 in devctl2_ioctl (cdev=, cmd=, data=0xfffff8002bf80200 "uhub0", fflag=, td=) at /usr/src/sys/kern/subr_bus.c:1776 #22 0xffffffff80a8622a in devfs_ioctl (ap=0xfffffe0017f97728) at /usr/src/sys/fs/devfs/devfs_vnops.c:834 #23 0xffffffff81220263 in VOP_IOCTL_APV ( vop=0xffffffff81aeb458 , a=0xfffffe0017f97728) at vnode_if.c:1052 #24 0xffffffff80cb062d in vn_ioctl (fp=0xfffff80003cce960, com=, data=0xfffff8002bf80200, active_cred=0xfffff800032ba500, td=0x246) at /usr/src/sys/kern/vfs_vnops.c:1492 #25 0xffffffff80a868bf in devfs_ioctl_f (fp=0xfffff800031ff400, com=18446744071590345336, data=0x18, cred=0x0, td=0xfffff8002b3d1000) at /usr/src/sys/fs/devfs/devfs_vnops.c:766 #26 0xffffffff80c3ae2a in fo_ioctl (fp=, com=, data=0xffffffff81fd09d0 , active_cred=0x0, td=) at /usr/src/sys/sys/file.h:333 #27 kern_ioctl (td=, fd=, com=2157462531, data=0xffffffff81fd09d0 "") at /usr/src/sys/kern/sys_generic.c:800 #28 0xffffffff80c3ab2d in sys_ioctl (td=0xfffff8002b3d1000, uap=0xfffff8002b3d13c8) at /usr/src/sys/kern/sys_generic.c:712 #29 0xffffffff8109ab2b in syscallenter (td=0xfffff8002b3d1000) at /usr/src/sys/amd64/amd64/../../kern/subr_syscall.c:144 #30 amd64_syscall (td=0xfffff8002b3d1000, traced=0) at /usr/src/sys/amd64/amd64/trap.c:1180 #31 #32 0x000000080041a31a in ?? () Backtrace stopped: Cannot access memory at address 0x7fffffffea38 (kgdb) Please confirm and let me know if any other info required. -- Thank you! Sincere regards, Neeraj Pal