kern/146082: ng_l2tp: a false invaliant check was performed in ng_l2tp_seq_check()

Yoshihiko Sarumaru sarumaru at yamayuri.org
Tue Apr 27 09:30:09 UTC 2010


>Number:         146082
>Category:       kern
>Synopsis:       ng_l2tp: a false invaliant check was performed in ng_l2tp_seq_check()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 27 09:30:08 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Yoshihiko Sarumaru
>Release:        7.2-RELEASE-p7
>Organization:
>Environment:
FreeBSD yumi.yamayuri.org 7.2-RELEASE-p7 FreeBSD 7.2-RELEASE-p7 #4: Sat Feb 27 22:15:11 JST 2010     root at yumi.yamayuri.org:/usr/obj/usr/src/sys/YUMI  i386

>Description:
Sometimes the same panic was observed in my FreeBSD IPv6 box + L2TP tunnel.

In ng_l2tp_seq_check(), peer_nack was ensured positive value by:

/* Compare sequence numbers using circular math */
#define L2TP_SEQ_DIFF(x, y)     ((int)((int16_t)(x) - (int16_t)(y)))

        int self_unack, peer_unack;
        peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack);
        CHECK(peer_unack >= 0);
(picked up from src/sys/netgraph/ng_l2tp.c)

While (seq->ns >= 32768 && seq->rack < 32768) is true, 
this MACRO introduce a false value, and cause a panic.
(ns and rack are uint16_t variable)

NOTE: this function is effective when INVARIANT option was set.

backtrace:
#0  doadump () at pcpu.h:196
#1  0xc07ffbce in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:418
#2  0xc07ffea2 in panic (fmt=Variable "fmt" is not available.
) at /usr/src/sys/kern/kern_shutdown.c:574
#3  0xc473baf0 in ng_l2tp_seq_check (seq=0xc41fa468)
    at /usr/src/sys/modules/netgraph/l2tp/../../../netgraph/ng_l2tp.c:1588
#4  0xc473c301 in ng_l2tp_rcvdata_ctrl (hook=0xc4614e80, item=0xc4739270)
    at /usr/src/sys/modules/netgraph/l2tp/../../../netgraph/ng_l2tp.c:1088
#5  0xc46ba0af in ng_apply_item (node=0xc4614d80, item=0xc4739270, rw=0)
    at /usr/src/sys/modules/netgraph/netgraph/../../../netgraph/ng_base.c:2336
#6  0xc46bb701 in ng_snd_item (item=0xc4739270, flags=Variable "flags" is not av
ailable.
)
    at /usr/src/sys/modules/netgraph/netgraph/../../../netgraph/ng_base.c:2254
#7  0xc46b2ad5 in ngd_send (so=0xc4738000, flags=0, m=0xc452a600,
    addr=0xc445e880, control=0x0, td=0xc46af460)
    at /usr/src/sys/modules/netgraph/socket/../../../netgraph/ng_socket.c:445
#8  0xc085e68d in sosend_generic (so=0xc4738000, addr=0xc445e880,
    uio=0xe67f2be8, top=0xc452a600, control=0x0, flags=0, td=0xc46af460)
    at /usr/src/sys/kern/uipc_socket.c:1246
#9  0xc085a89f in sosend (so=0xc4738000, addr=0xc445e880, uio=0xe67f2be8,
    top=0x0, control=0x0, flags=0, td=0xc46af460)
    at /usr/src/sys/kern/uipc_socket.c:1288
#10 0xc0861d16 in kern_sendit (td=0xc46af460, s=10, mp=0xe67f2c64, flags=0,
    control=0x0, segflg=UIO_USERSPACE) at /usr/src/sys/kern/uipc_syscalls.c:805
#11 0xc0863f01 in sendit (td=0xc46af460, s=10, mp=0xe67f2c64, flags=0)
    at /usr/src/sys/kern/uipc_syscalls.c:742
#12 0xc0864018 in sendto (td=0xc46af460, uap=0xe67f2cfc)
    at /usr/src/sys/kern/uipc_syscalls.c:857
#13 0xc0af65b3 in syscall (frame=0xe67f2d38)
    at /usr/src/sys/i386/i386/trap.c:1090
#14 0xc0adad40 in Xint0x80_syscall () at /usr/src/sys/i386/i386/exception.s:255
---Type <return> to continue, or q <return> to quit---
#15 0x00000033 in ?? ()
Previous frame inner to this frame (corrupt stack?)

state of *seq:
(kgdb) print *seq
$4 = {ns = 32768, nr = 2, inproc = 0, rack = 32767, xack = 2, wmax = 128,
  cwnd = 128, ssth = 1, acks = 0, rexmits = 0, rack_timer = {c_links = {sle = {
        sle_next = 0x0}, tqe = {tqe_next = 0x0, tqe_prev = 0xd80934a8}},
    c_time = 1965926795, c_arg = 0xc4a0b270,
    c_func = 0xc46bb9b0 <ng_callout_trampoline>, c_mtx = 0x0, c_flags = 18},
  xack_timer = {c_links = {sle = {sle_next = 0x0}, tqe = {tqe_next = 0x0,
        tqe_prev = 0xd809ebd0}}, c_time = 16496, c_arg = 0x0,
    c_func = 0xc46bb9b0 <ng_callout_trampoline>, c_mtx = 0x0, c_flags = 16},
  xwin = {0xc452a600, 0x0 <repeats 127 times>}, mtx = {lock_object = {
      lo_name = 0xc473e16f "ng_l2tp", lo_type = 0xc473e16f "ng_l2tp",
      lo_flags = 16973824, lo_witness_data = {lod_list = {
          stqe_next = 0xc0cfc9f0}, lod_witness = 0xc0cfc9f0}},
    mtx_lock = 3295343714, mtx_recurse = 0}}

>How-To-Repeat:
make an L2TP tunnel with ng_l2tp, then send and receive packet to/from that
interface for a long time (1-3 months in my home). 

INVARIANT option is required for your kernel.
>Fix:
I'm not sure.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list