Date: Fri, 16 Sep 2022 10:10:59 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 266442] kernel page fault on packet with broken lengths if ipfilter is loaded Message-ID: <bug-266442-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D266442 Bug ID: 266442 Summary: kernel page fault on packet with broken lengths if ipfilter is loaded 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 Attachment #236590 text/plain mime type: Created attachment 236590 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D236590&action= =3Dedit Inject a packet that causes a kernel page fault if ipfilter is loaded. If ipfilter is loaded, and a packet arrives with IP hlen =3D 20 bytes (the default), IP packet len =3D 67 bytes, and TCP th_off =3D 48 bytes, ipf_pullup() will call m_pullup(len=3D68), which fails and causes ipf_pullup() to free the mbuf and zero out the mbuf pointer in *fin->fin_mp. But the information that the packet was discarded is lost because ipf_pr_ipv4hdr() does not return an error to ipf_makefrip(). So the calling code thinks everything is OK, ip_tryforward() sees PFIL_PASS and uses m =3D *fin->fin_mp, and it crashes. Error indications should probably be made to flow up from ipf_pullup() through ipf_pr_ipv4hdr() to ipf_makefrip(), so that callers know not to try to use the freed mbuf. I've attached a demo: # cc -o pf7a pf7a.c # ./pf7a ... panic: Fatal page fault at 0xffffffc000488f14: 0x0000000000001d panic() at panic+0x2a page_fault_handler() at page_fault_handler+0x1d6 do_trap_supervisor() at do_trap_supervisor+0x76 cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70 --- exception 13, tval =3D 0x1d ip_tryforward() at ip_tryforward+0x278 ip_input() at ip_input+0x356 netisr_dispatch_src() at netisr_dispatch_src+0xca netisr_dispatch() at netisr_dispatch+0x10 tunwrite_l3() at tunwrite_l3+0x182 tunwrite() at tunwrite+0x128 devfs_write_f() at devfs_write_f+0xa6 fo_write() at fo_write+0xa dofilewrite() at dofilewrite+0x66 kern_writev() at kern_writev+0x40 sys_write() at sys_write+0x54 syscallenter() at syscallenter+0xec ecall_handler() at ecall_handler+0x18 do_trap_user() at do_trap_user+0xea cpu_exception_handler_user() at cpu_exception_handler_user+0x72 Here's the call chain at the point where m_pullup() fails: ipf_pullup() at ipf_pullup+0x182 ipf_pr_pullup() at ipf_pr_pullup+0x5c ipf_pr_tcpcommon() at ipf_pr_tcpcommon+0x28e ipf_pr_tcp() at ipf_pr_tcp+0x46 ipf_pr_ipv4hdr() at ipf_pr_ipv4hdr+0x220 ipf_makefrip() at ipf_makefrip+0x60 ipf_check() at ipf_check+0x142 ipf_check_wrapper() at ipf_check_wrapper+0x88 pfil_mbuf_in() at pfil_mbuf_in+0x58 ip_tryforward() at ip_tryforward+0x1c0 ip_input() at ip_input+0x356 --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-266442-227>