panic: tcp_addoptions: TCP options too long w/ with TCP_SIGNATURE support

Andre Oppermann andre at freebsd.org
Tue Apr 1 13:00:39 PDT 2008


Mark Atkinson wrote:
> Rui Paulo wrote:
> 
>> Hi,
>>
>> On Tue, Apr 01, 2008 at 09:08:35AM -0700, Mark Atkinson wrote:
>>> I have a 8-CURRENT kernel compiled with the following options, from about
>>> march 5th.
>>>
>>> options        IPSEC
>>> options        TCP_SIGNATURE           #include support for RFC 2385
>>> device         crypto
>>> device         cryptodev
>>>
>>> device          pf
>>> device          pflog
>>>
>>> device         vlan
>>>
>>> I also have a external server supporting MD5 tcp signatures.  If I give
>>> the following command:
>>>
>>> /usr/src/tools/regression/netinet/tcpconnect/tcpconnect client
>>> 172.16.1.145 7 1 tcpmd5
>>>
>>> panic: tcp_addoptions: TCP options too long
>> Could you please use gdb or add a printf to find the value of optlen ?
>>
> 
> $ kgdb kernel.debug /var/crash/vmcore.2
> [GDB will not be able to debug user-mode threads: /usr/lib/libthread_db.so:
> Undefined symbol "ps_pglobal_lookup"]
> GNU gdb 6.1.1 [FreeBSD]
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain
> conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB.  Type "show warranty" for details.
> This GDB was configured as "i386-marcel-freebsd".
> Reading symbols from /boot/kernel/acpi.ko...Reading symbols
> from /boot/kernel/acpi.ko.symbols...done.
> done.
> Loaded symbols for /boot/kernel/acpi.ko
> Reading symbols from /boot/kernel/ipfw.ko...Reading symbols
> from /boot/kernel/ipfw.ko.symbols...done.
> done.
> Loaded symbols for /boot/kernel/ipfw.ko
> 
> Unread portion of the kernel message buffer:
> panic: tcp_addoptions: TCP options too long
> cpuid = 1
> KDB: enter: panic
> Physical memory: 2034 MB
> Dumping 79 MB: 64 48 32 16
> 
> #0  doadump () at pcpu.h:195
> 195             __asm __volatile("movl %%fs:0,%0" : "=r" (td));
> (kgdb) bt
> #0  doadump () at pcpu.h:195
> #1  0xc04c7159 in db_fncall (dummy1=1017, dummy2=0, dummy3=1019,
> dummy4=0xe7b808b0 "ø\003") at /usr/src/sys/ddb/db_command.c:516
> #2  0xc04c76dc in db_command (last_cmdp=0xc0c5c7b4, cmd_table=0x0,
> dopager=1) at /usr/src/sys/ddb/db_command.c:413
> #3  0xc04c77ea in db_command_loop () at /usr/src/sys/ddb/db_command.c:466
> #4  0xc04c8fec in db_trap (type=3, code=0) at /usr/src/sys/ddb/db_main.c:228
> #5  0xc07cf325 in kdb_trap (type=3, code=0, tf=0xe7b80a58)
> at /usr/src/sys/kern/subr_kdb.c:510
> #6  0xc0ac8d5f in trap (frame=0xe7b80a58)
> at /usr/src/sys/i386/i386/trap.c:643
> #7  0xc0aad7cb in calltrap () at /usr/src/sys/i386/i386/exception.s:146
> #8  0xc07cf4aa in kdb_enter (why=0xc0b62ce8 "panic", msg=0xc0b62ce8 "panic")
> at cpufunc.h:60
> #9  0xc07a67cc in panic (fmt=0xc0b78840 "%s: TCP options too long")
> at /usr/src/sys/kern/kern_shutdown.c:556
> #10 0xc08e8207 in tcp_addoptions (to=0xe7b80ba4,
> optp=0xe7b80bc0 "\002\004\005´\001\003\003\003\001\001\b\n")
> at /usr/src/sys/netinet/tcp_output.c:1402
> #11 0xc08e8c79 in tcp_output (tp=0xc576d570)
> at /usr/src/sys/netinet/tcp_output.c:693
> #12 0xc08f4f35 in tcp_usr_connect (so=0xc5709794, nam=0xc5260280,
> td=0xc5729210) at tcp_offload.h:251
> #13 0xc07ff092 in soconnect (so=0xc5709794, nam=0xc5260280, td=0xc5729210)
> at /usr/src/sys/kern/uipc_socket.c:765
> #14 0xc0805436 in kern_connect (td=0xc5729210, fd=3, sa=0xc5260280)
> at /usr/src/sys/kern/uipc_syscalls.c:560
> #15 0xc08055a6 in connect (td=0xc5729210, uap=0xe7b80cfc)
> at /usr/src/sys/kern/uipc_syscalls.c:524
> #16 0xc0ac8513 in syscall (frame=0xe7b80d38)
> at /usr/src/sys/i386/i386/trap.c:1026
> #17 0xc0aad830 in Xint0x80_syscall ()
> at /usr/src/sys/i386/i386/exception.s:203
> #18 0x00000033 in ?? ()
> Previous frame inner to this frame (corrupt stack?)
> (kgdb) frame 10
> #10 0xc08e8207 in tcp_addoptions (to=0xe7b80ba4,
> optp=0xe7b80bc0 "\002\004\005´\001\003\003\003\001\001\b\n")
> at /usr/src/sys/netinet/tcp_output.c:1402
> 1402            KASSERT(optlen <= TCP_MAXOLEN, ("%s: TCP options too long",
> __func__));
> (kgdb) p optlen
> $1 = 44
> (kgdb)

The order of the TCP options was changed recently to fix another problem.
This has caused sub-optimal padding and this overflow as not all options
fit.  The tcp_addoptions() loop is not bound internally.

http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/tcp_output.c?rev=1.146

-- 
Andre


More information about the freebsd-net mailing list