Created attachment 246521 [details] small test program to trigger a page fault in the kqueue(2) code While I was experimenting with kqueue(2) and rfork(2), a page fault was triggered. When using fork(2) this problem does not occur. The panic is reproducible with the attached code. It is also reproducible on FreeBSD 14.0. The following is from the generated crash info: 13.2-RELEASE-p4 FreeBSD 13.2-RELEASE-p4 releng/13.2-n254638-d20ece445acf GENERIC amd64 panic: page fault GNU gdb (GDB) 13.2 [GDB v13.2 for FreeBSD] Copyright (C) 2023 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 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.2". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. 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: [112] [112] [112] Fatal trap 12: page fault while in kernel mode [112] cpuid = 7; apic id = 27 [112] fault virtual address = 0x20 [112] fault code = supervisor read data, page not present [112] instruction pointer = 0x20:0xffffffff8071161b [112] stack pointer = 0x28:0xfffffe042eac9b00 [112] frame pointer = 0x28:0xfffffe042eac9b20 [112] code segment = base rx0, limit 0xfffff, type 0x1b [112] = DPL 0, pres 1, long 1, def32 0, gran 1 [112] processor eflags = interrupt enabled, resume, IOPL = 0 [112] current process = 99300 (test) [112] trap number = 12 [112] panic: page fault [112] cpuid = 7 [112] time = 1698479858 [112] KDB: stack backtrace: [112] #0 0xffffffff807ae505 at kdb_backtrace+0x65 [112] #1 0xffffffff80760e81 at vpanic+0x151 [112] #2 0xffffffff80760d23 at panic+0x43 [112] #3 0xffffffff80abffa7 at trap_fatal+0x387 [112] #4 0xffffffff80abffff at trap_pfault+0x4f [112] #5 0xffffffff80a97108 at calltrap+0x8 [112] #6 0xffffffff80710fe8 at kqueue_drain+0x258 [112] #7 0xffffffff80712462 at kqueue_close+0x42 [112] #8 0xffffffff80702ac1 at _fdrop+0x11 [112] #9 0xffffffff8070607b at closef+0x24b [112] #10 0xffffffff8070593c at fdescfree_fds+0xdc [112] #11 0xffffffff807053e5 at fdescfree+0x3b5 [112] #12 0xffffffff807178e7 at exit1+0x4d7 [112] #13 0xffffffff8071740d at sys_sys_exit+0xd [112] #14 0xffffffff80ac089c at amd64_syscall+0x10c [112] #15 0xffffffff80a97a1b at fast_syscall_common+0xf8 [112] Uptime: 1m52s [112] Dumping 8596 out of 262104 MB:..1%..11%..21%..31%..41%..51%..61%..71%..81%..91% __curthread () at /usr/src/sys/amd64/include/pcpu_aux.h:55 55 __asm("movq %%gs:%P1,%0" : "=r" (td) : "n" (offsetof(struct pcpu, (kgdb) #0 __curthread () at /usr/src/sys/amd64/include/pcpu_aux.h:55 #1 doadump (textdump=<optimized out>) at /usr/src/sys/kern/kern_shutdown.c:396 #2 0xffffffff80760a4a in kern_reboot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:484 #3 0xffffffff80760eee in vpanic (fmt=<optimized out>, ap=ap@entry=0xfffffe042eac9950) at /usr/src/sys/kern/kern_shutdown.c:923 #4 0xffffffff80760d23 in panic (fmt=<unavailable>) at /usr/src/sys/kern/kern_shutdown.c:847 #5 0xffffffff80abffa7 in trap_fatal (frame=0xfffffe042eac9a40, eva=32) at /usr/src/sys/amd64/amd64/trap.c:942 #6 0xffffffff80abffff in trap_pfault (frame=0xfffffe042eac9a40, usermode=false, signo=<optimized out>, ucode=<optimized out>) at /usr/src/sys/amd64/amd64/trap.c:761 #7 <signal handler called> #8 knlist_remove_kq (knl=0x0, kn=0xfffff8284882e5a0, knlislocked=0, kqislocked=0) at /usr/src/sys/kern/kern_event.c:2447 #9 0xffffffff80710fe8 in knote_drop (kn=0xfffff8284882e5a0, td=0xfffffe01c6244720) at /usr/src/sys/kern/kern_event.c:2736 #10 kqueue_drain (kq=kq@entry=0xfffff828481c5300, td=td@entry=0xfffffe01c6244720) at /usr/src/sys/kern/kern_event.c:2240 #11 0xffffffff80712462 in kqueue_close (fp=0xfffff8284816eaa0, td=0xfffffe01c6244720) at /usr/src/sys/kern/kern_event.c:2289 #12 0xffffffff80702ac1 in fo_close (fp=0x0, fp@entry=0xfffff8284816eaa0, td=0xfffff8284882e5a0, td@entry=0xfffffe01c6244720) at /usr/src/sys/sys/file.h:384 #13 _fdrop (fp=0x0, fp@entry=0xfffff8284816eaa0, td=0xfffff8284882e5a0, td@entry=0xfffffe01c6244720) at /usr/src/sys/kern/kern_descrip.c:3691 #14 0xffffffff8070607b in closef (fp=fp@entry=0xfffff8284816eaa0, td=td@entry=0xfffffe01c6244720) at /usr/src/sys/kern/kern_descrip.c:2937 #15 0xffffffff8070593c in fdescfree_fds (td=0xfffff8284882e5a0, td@entry=0xfffffe01c6244720, fdp=fdp@entry=0xfffffe01cc6b9000, needclose=false) at /usr/src/sys/kern/kern_descrip.c:2644 #16 0xffffffff807053e5 in fdescfree (td=td@entry=0xfffffe01c6244720) at /usr/src/sys/kern/kern_descrip.c:2690 #17 0xffffffff807178e7 in exit1 (td=0xfffffe01c6244720, rval=<optimized out>, signo=signo@entry=0) at /usr/src/sys/kern/kern_exit.c:403 #18 0xffffffff8071740d in sys_sys_exit (td=0x0, uap=<optimized out>) at /usr/src/sys/kern/kern_exit.c:212 #19 0xffffffff80ac089c in syscallenter (td=0xfffffe01c6244720) at /usr/src/sys/amd64/amd64/../../kern/subr_syscall.c:190 #20 amd64_syscall (td=0xfffffe01c6244720, traced=0) at /usr/src/sys/amd64/amd64/trap.c:1183 #21 <signal handler called> #22 0x00000008240e504a in ?? () Backtrace stopped: Cannot access memory at address 0x82026a5c8 (kgdb)
https://reviews.freebsd.org/D42745
Created attachment 246539 [details] regression test I took the liberty of distilling the test case into a regression test, attached.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=393ac29f0b8be068c8e46f76c2eeee07d20ea4df commit 393ac29f0b8be068c8e46f76c2eeee07d20ea4df Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-24 06:41:58 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-11-24 16:26:53 +0000 kqueue: on process exit, force-clear its registered signal events Normally, process already has all its kqueue fds destroyed at the moment p_klist is detached in exit flow. But, if the process was created with rfork(2) with shared file descriptors, its signal knotes can survive. Then, knlist_detach() does not destroy non-empty knlist. Later, when owning kqueue is closed, we access freed (or rather, reused, because struct proc is type-stable) memory by referencing p->p_klist from such knote. Handle this situation by deleting all knotes hanging from p_klist. PR: 275286 Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D42745 sys/kern/kern_exit.c | 1 + 1 file changed, 1 insertion(+)
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=ed410b78edc53e17b5a3e93ace2adbeb3a734ae9 commit ed410b78edc53e17b5a3e93ace2adbeb3a734ae9 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:51:54 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-11-28 17:29:58 +0000 EVFILT_SIGNAL: do not use target process pointer on detach It is enough to know knlist to remove from it, and the list is autodestroyed on last removal. PR: 275286 Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D42777 sys/kern/kern_sig.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=877ef685322f795c071da9657bb490730d8cbb89 commit 877ef685322f795c071da9657bb490730d8cbb89 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:32:24 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-11-28 17:29:58 +0000 Revert "kqueue: on process exit, force-clear its registered signal events" This reverts commit 393ac29f0b8be068c8e46f76c2eeee07d20ea4df. A different fix is following, which preserves semantic, required by the sys.kqueue.proc3_test.proc3 test. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week PR: 275286 Differential revision: https://reviews.freebsd.org/D42777 sys/kern/kern_exit.c | 1 - 1 file changed, 1 deletion(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=24346a2f777598272caffbd7e4fb6d85cafe64ed commit 24346a2f777598272caffbd7e4fb6d85cafe64ed Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:51:54 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-12-05 00:43:27 +0000 EVFILT_SIGNAL: do not use target process pointer on detach PR: 275286 (cherry picked from commit ed410b78edc53e17b5a3e93ace2adbeb3a734ae9) sys/kern/kern_sig.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=55e91944998c128d74b94b9b48a04ef41ff5e9d0 commit 55e91944998c128d74b94b9b48a04ef41ff5e9d0 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:51:54 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-12-05 00:44:13 +0000 EVFILT_SIGNAL: do not use target process pointer on detach PR: 275286 (cherry picked from commit ed410b78edc53e17b5a3e93ace2adbeb3a734ae9) sys/kern/kern_sig.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
*** Bug 269520 has been marked as a duplicate of this bug. ***
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=f5463265955b829775bbb32e1fd0bc11dafc36ce commit f5463265955b829775bbb32e1fd0bc11dafc36ce Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-11-24 15:28:13 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2024-01-27 18:51:13 +0000 kqueue tests: Add a regression test Based on the test case submitted by Andreas Bock for PR 275286. PR: 275286 MFC after: 2 weeks tests/sys/kqueue/Makefile | 4 +- tests/sys/kqueue/kqueue_fork.c (new) | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-)
IMO this deserves an EN as the regression test can not be run on 14.0 without a panic.
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=3a90a4453750b12444e96d647d7c1203dc1cc9c5 commit 3a90a4453750b12444e96d647d7c1203dc1cc9c5 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-11-24 15:28:13 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2024-02-11 15:14:44 +0000 kqueue tests: Add a regression test Based on the test case submitted by Andreas Bock for PR 275286. PR: 275286 MFC after: 2 weeks (cherry picked from commit f5463265955b829775bbb32e1fd0bc11dafc36ce) tests/sys/kqueue/Makefile | 4 +- tests/sys/kqueue/kqueue_fork.c (new) | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-)
A commit in branch releng/14.0 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=bb06104dce0b2d471772fefe2ce5b7e651287479 commit bb06104dce0b2d471772fefe2ce5b7e651287479 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:51:54 +0000 Commit: Gordon Tetlow <gordon@FreeBSD.org> CommitDate: 2024-02-14 05:37:56 +0000 EVFILT_SIGNAL: do not use target process pointer on detach PR: 275286 Approved by: so Security: FreeBSD-EN-24:03.kqueue (cherry picked from commit ed410b78edc53e17b5a3e93ace2adbeb3a734ae9) (cherry picked from commit 24346a2f777598272caffbd7e4fb6d85cafe64ed) sys/kern/kern_sig.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
A commit in branch releng/13.2 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=154dedade4654516dfd3737ae56d5b3e3721029a commit 154dedade4654516dfd3737ae56d5b3e3721029a Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-28 12:51:54 +0000 Commit: Gordon Tetlow <gordon@FreeBSD.org> CommitDate: 2024-02-14 05:37:16 +0000 EVFILT_SIGNAL: do not use target process pointer on detach PR: 275286 Approved by: so Security: FreeBSD-EN-24:03.kqueue (cherry picked from commit ed410b78edc53e17b5a3e93ace2adbeb3a734ae9) (cherry picked from commit 55e91944998c128d74b94b9b48a04ef41ff5e9d0) sys/kern/kern_sig.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)