Bug 217391 - [ipfw] [panic] erroneous ipfw rule triggers KASSERT
Summary: [ipfw] [panic] erroneous ipfw rule triggers KASSERT
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 11.0-STABLE
Hardware: Any Any
: --- Affects Some People
Assignee: Andrey V. Elsukov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-27 13:07 UTC by Eugene Grosbein
Modified: 2017-03-13 08:05 UTC (History)
2 users (show)

See Also:


Attachments
Proposed patch (609 bytes, patch)
2017-03-04 01:46 UTC, Andrey V. Elsukov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eugene Grosbein 2017-02-27 13:07:17 UTC
Next three commands trigger KASSERT/panic for INVARIANTS-enabled kernel:

ipfw table 1 create type addr
ipfw add 1 count ip from any to any in recv 'table(10)' # pilot error
ipfw flush # (or "service ipfw start" as it includes flush)

Kernel built without INVARIANTS works fine.

Panic message: panic: wrong type 1 (2) for table id 1

Backtrace follows:

(kgdb) bt
#0  doadump (textdump=1) at pcpu.h:222
#1  0xffffffff80590ac5 in kern_reboot (howto=<value optimized out>)
    at /data2/src/sys/kern/kern_shutdown.c:366
#2  0xffffffff805910a0 in vpanic (fmt=<value optimized out>,
    ap=<value optimized out>) at /data2/src/sys/kern/kern_shutdown.c:759
#3  0xffffffff80590ed6 in kassert_panic (fmt=<value optimized out>)
    at /data2/src/sys/kern/kern_shutdown.c:649
#4  0xffffffff8072c784 in unref_rule_objects (ch=0xffffffff80ec6610,
    rule=<value optimized out>)
    at /data2/src/sys/netpfil/ipfw/ip_fw_sockopt.c:2613
#5  0xffffffff80732503 in delete_range (chain=<value optimized out>,
    rt=0xfffffe0238c907c8, ndel=<value optimized out>)
    at /data2/src/sys/netpfil/ipfw/ip_fw_sockopt.c:803
#6  0xffffffff80730c50 in del_rules (chain=0xffffffff80ec6610,
    op3=<value optimized out>, sd=0xfffffe0238c90740)
    at /data2/src/sys/netpfil/ipfw/ip_fw_sockopt.c:1265
#7  0xffffffff8072e2cd in ipfw_ctl3 (sopt=0xfffffe0238c909b0)
    at /data2/src/sys/netpfil/ipfw/ip_fw_sockopt.c:3674
#8  0xffffffff806ddd62 in rip_ctloutput (so=0xfffff8017c82a360,
    sopt=0xfffffe0238c909b0) at /data2/src/sys/netinet/raw_ip.c:596
#9  0xffffffff806222a9 in sogetopt (so=0xfffff8017c82a360,
    sopt=0xfffffe0238c909b0) at /data2/src/sys/kern/uipc_socket.c:2743
#10 0xffffffff8062678e in kern_getsockopt (td=0xfffff801b10fd000,
---Type <return> to continue, or q <return> to quit---
    s=<value optimized out>, level=<value optimized out>,
    name=<value optimized out>, val=<value optimized out>,
    valseg=<value optimized out>, valsize=0xfffffe0238c90a1c)
    at /data2/src/sys/kern/uipc_syscalls.c:1489
#11 0xffffffff80626690 in sys_getsockopt (td=0xfffff801b10fd000,
    uap=0xfffffe0238c90b30) at /data2/src/sys/kern/uipc_syscalls.c:1435
#12 0xffffffff8083316c in amd64_syscall (td=0xfffff801b10fd000, traced=0)
    at subr_syscall.c:135
#13 0xffffffff8081486b in Xfast_syscall ()
    at /data2/src/sys/amd64/amd64/exception.S:396
#14 0x0000000800b3a9da in ?? ()
Current language:  auto; currently minimal
(kgdb) frame 4
#4  0xffffffff8072c784 in unref_rule_objects (ch=0xffffffff80ec6610, 
    rule=<value optimized out>)
    at /data2/src/sys/netpfil/ipfw/ip_fw_sockopt.c:2613
2613                    KASSERT(no->subtype == subtype,
(kgdb) l
2608                    if (rw == NULL)
2609                            continue;
2610                    no = rw->find_bykidx(ch, kidx);
2611    
2612                    KASSERT(no != NULL, ("table id %d not found", kidx));
2613                    KASSERT(no->subtype == subtype,
2614                        ("wrong type %d (%d) for table id %d",
2615                        no->subtype, subtype, kidx));
2616                    KASSERT(no->refcnt > 0, ("refcount for table %d is %d",
2617                        kidx, no->refcnt));
(kgdb)
Comment 1 Eugene Grosbein 2017-02-27 13:09:41 UTC
Small correction to "how-to-repeat" commands: table number should be the same for both ipfw commands.

ipfw table 10 create type addr
ipfw add 1 count ip from any to any in recv 'table(10)'
ipfw flush
Comment 2 Andrey V. Elsukov freebsd_committer freebsd_triage 2017-03-04 01:46:28 UTC
Created attachment 180481 [details]
Proposed patch

I think this patch should fix the problem. Can you test it?
Comment 3 Eugene Grosbein 2017-03-05 11:01:19 UTC
Thanks, this patch really helps. Now second command (with error) gets rejected by the kernel:

# ipfw add 1 count ip from any to any in recv 'table(10)'
ipfw: getsockopt(IP_FW_XADD): Invalid argument
Comment 4 commit-hook freebsd_committer freebsd_triage 2017-03-05 22:20:04 UTC
A commit references this bug:

Author: ae
Date: Sun Mar  5 22:19:43 UTC 2017
New revision: 314715
URL: https://svnweb.freebsd.org/changeset/base/314715

Log:
  Reject invalid object types that can not be used with specific opcodes.

  When we doing reference counting of named objects in the new rule,
  for existing objects check that opcode references to correct object,
  otherwise return EINVAL.

  PR:		217391
  MFC after:	1 week
  Sponsored by:	Yandex LLC

Changes:
  head/sys/netpfil/ipfw/ip_fw_sockopt.c
Comment 5 commit-hook freebsd_committer freebsd_triage 2017-03-13 08:04:44 UTC
A commit references this bug:

Author: ae
Date: Mon Mar 13 08:04:25 UTC 2017
New revision: 315191
URL: https://svnweb.freebsd.org/changeset/base/315191

Log:
  MFC r314715:
    Reject invalid object types that can not be used with specific opcodes.

    When we doing reference counting of named objects in the new rule,
    for existing objects check that opcode references to correct object,
    otherwise return EINVAL.

    PR:		217391

Changes:
_U  stable/11/
  stable/11/sys/netpfil/ipfw/ip_fw_sockopt.c