Bug 197882

Summary: [panic] kernel panics in soreceive_dgram
Product: Base System Reporter: Andrey V. Elsukov <ae>
Component: kernAssignee: Andrey V. Elsukov <ae>
Status: Closed FIXED    
Severity: Affects Some People    
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
text dump
none
test program to reproduce none

Description Andrey V. Elsukov freebsd_committer freebsd_triage 2015-02-21 17:12:33 UTC
Created attachment 153281 [details]
text dump

I wrote small program to test changes in ipv6 code, but it triggers panic in generic socket's code.

Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00
fault virtual address   = 0x1c
fault code              = supervisor read data, page not present
instruction pointer     = 0x20:0xffffffff809de6dc
stack pointer           = 0x28:0xfffffe066064a7c0
frame pointer           = 0x28:0xfffffe066064a840
code segment            = base rx0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 885 (test)

#9  0xffffffff80d93f42 in calltrap ()
    at /home/devel/freebsd/base/head/sys/amd64/amd64/exception.S:235
#10 0xffffffff809de6dc in soreceive_dgram (so=<value optimized out>, 
    psa=0xfffffe066064a8c0, uio=0xfffffe066064a8d0, 
    mp0=<value optimized out>, controlp=<value optimized out>, 
    flagsp=0xfffffe066064a97c)
    at /home/devel/freebsd/base/head/sys/kern/uipc_socket.c:2271
#11 0xffffffff809de88e in soreceive (so=0xfffff8002379b700, psa=0x100, 
    uio=0xfc, mp0=0x0, controlp=0xffffffff81542158, flagsp=0x8)
    at /home/devel/freebsd/base/head/sys/kern/uipc_socket.c:2321
#12 0xffffffff809e3938 in kern_recvit (td=0xfffff80012dda940, s=3, 
    mp=0xfffffe066064a950, fromseg=UIO_USERSPACE, controlp=0x0)
    at /home/devel/freebsd/base/head/sys/kern/uipc_syscalls.c:1102
#13 0xffffffff809e3ccf in sys_recvmsg (td=0xfffff80012dda940, 
    uap=0xfffffe066064aa40)
    at /home/devel/freebsd/base/head/sys/kern/uipc_syscalls.c:1214
#14 0xffffffff80db675f in amd64_syscall (td=0xfffff80012dda940, traced=0)
    at subr_syscall.c:133
Comment 1 Andrey V. Elsukov freebsd_committer freebsd_triage 2015-02-21 17:16:29 UTC
Created attachment 153282 [details]
test program to reproduce

This program works on 10-STABLE, but on 11-CURRENT it triggers the panic.
To reproduce you need ethernet interface with enabled IPv6 and MTU less that 2000:

em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=4219b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_MAGIC,VLAN_HWTSO>
	ether 00:22:4d:6a:5e:b9
	inet6 fe80::222:4dff:fe6a:5eb9%em0 prefixlen 64 scopeid 0x1 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active

% ./test fe80::1%em0
Comment 2 Andrey V. Elsukov freebsd_committer freebsd_triage 2015-02-22 18:01:32 UTC
I found that kernel without INVARIANTS and WITNESS doesn't panic.
Comment 3 commit-hook freebsd_committer freebsd_triage 2015-02-23 13:42:24 UTC
A commit references this bug:

Author: ae
Date: Mon Feb 23 13:41:36 UTC 2015
New revision: 279206
URL: https://svnweb.freebsd.org/changeset/base/279206

Log:
  In some cases soreceive_dgram() can return no data, but has control
  message. This can happen when application is sending packets too big
  for the path MTU and recvmsg() will return zero (indicating no data)
  but there will be a cmsghdr with cmsg_type set to IPV6_PATHMTU.
  Remove KASSERT() which does NULL pointer dereference in such case.
  Also call m_freem() only when m isn't NULL.

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

Changes:
  head/sys/kern/uipc_socket.c
Comment 4 commit-hook freebsd_committer freebsd_triage 2015-03-02 07:51:37 UTC
A commit references this bug:

Author: ae
Date: Mon Mar  2 07:51:15 UTC 2015
New revision: 279516
URL: https://svnweb.freebsd.org/changeset/base/279516

Log:
  MFC r279206:
    In some cases soreceive_dgram() can return no data, but has control
    message. This can happen when application is sending packets too big
    for the path MTU and recvmsg() will return zero (indicating no data)
    but there will be a cmsghdr with cmsg_type set to IPV6_PATHMTU.
    Remove KASSERT() which does NULL pointer dereference in such case.
    Also call m_freem() only when m isn't NULL.

  MFC r279209:
    soreceive_generic() still has similar KASSERT(), therefore instead of
    remove KASSERT(), change it to check mbuf isn't NULL.

  PR:		197882
  Sponsored by:	Yandex LLC

Changes:
_U  stable/10/
  stable/10/sys/kern/uipc_socket.c
Comment 5 commit-hook freebsd_committer freebsd_triage 2015-03-02 08:00:39 UTC
A commit references this bug:

Author: ae
Date: Mon Mar  2 08:00:00 UTC 2015
New revision: 279517
URL: https://svnweb.freebsd.org/changeset/base/279517

Log:
  MFC r279206:
    In some cases soreceive_dgram() can return no data, but has control
    message. This can happen when application is sending packets too big
    for the path MTU and recvmsg() will return zero (indicating no data)
    but there will be a cmsghdr with cmsg_type set to IPV6_PATHMTU.
    Remove KASSERT() which does NULL pointer dereference in such case.
    Also call m_freem() only when m isn't NULL.

  MFC r279209:
    soreceive_generic() still has similar KASSERT(), therefore instead of
    remove KASSERT(), change it to check mbuf isn't NULL.

  PR:		197882
  Sponsored by:	Yandex LLC

Changes:
_U  stable/9/sys/
  stable/9/sys/kern/uipc_socket.c
Comment 6 Andrey V. Elsukov freebsd_committer freebsd_triage 2015-03-02 08:02:39 UTC
Fixed in stable/9 and stable/10.