Skip site navigation (1)Skip section navigation (2)
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>