Bug 112937 - [em] Panic in em(4) when issuing a SIOCGIFADDR ioctl
Summary: [em] Panic in em(4) when issuing a SIOCGIFADDR ioctl
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 7.0-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: jfv
URL:
Keywords: IntelNetworking
Depends on:
Blocks:
 
Reported: 2007-05-24 12:30 UTC by Fredrik Lindberg
Modified: 2015-06-29 17:53 UTC (History)
1 user (show)

See Also:


Attachments
if_em.c-20070524 (412 bytes, text/plain)
2007-05-24 12:30 UTC, Fredrik Lindberg
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Fredrik Lindberg 2007-05-24 12:30:05 UTC
The em-driver will panic if one issues a SIOCGIFADDR ioctl to a em-device
with only an inet6 address configured.

em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=18b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWCSUM,TSO4>
        ether 00:11:25:16:db:58
        inet6 fe80::211:25ff:fe16:db58%em0 prefixlen 64 scopeid 0x1
        media: Ethernet autoselect
        status: no carrier

Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00
fault virtual address   = 0x306d66
fault code              = supervisor read, page not present
instruction pointer     = 0x20:0xc087113b
stack pointer           = 0x28:0xe63b4b4c
frame pointer           = 0x28:0xe63b4b7c
code segment            = base rx0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 1576 (foo)

Backtrace
#9  0xc06ad62b in calltrap () at /usr/src/sys/i386/i386/exception.s:139
#10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
    data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
#11 0xc05e44ff in in6_control (so=0xc46cd318, cmd=3284147200,
    data=0xc48fcd80 "em0", ifp=0xc3c01c00, td=0xc4227000)
    at /usr/src/sys/netinet6/in6.c:785
#12 0xc059f258 in ifioctl (so=0xc46cd318, cmd=3223349537, data=0xc48fcd80 "em0",
    td=0xc4227000) at /usr/src/sys/net/if.c:1874
#13 0xc055ae97 in soo_ioctl (fp=0x306d65, cmd=3223349537, data=0xc48fcd80,
   active_cred=0xc4265700, td=0xc4227000) at /usr/src/sys/kern/sys_socket.c:202
#14 0xc0555dba in kern_ioctl (td=0xc4227000, fd=3, com=3223349537,
    data=0xc48fcd80 "em0") at file.h:266
#15 0xc0555bc5 in ioctl (td=0xc4227000, uap=0xe63b4d00)
    at /usr/src/sys/kern/sys_generic.c:542

The offending line is
(kgdb) f 10
#10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
    data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
977                     if (ifa->ifa_addr->sa_family == AF_INET) {

Fix: For SIOCGIFADDR the cast to a struct ifaddr is invalid and will cause
ifa_addr to point to a bogous address.
I believe it's safe to simply remove SIOCGIFADDR, the intialization shouldn't
be needed in this case.
How-To-Repeat: The following code should trigger the panic, but not if an inet4 address
is configured on the interface.

#include <string.h>
#include <sys/ioctl.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <net/if.h>

int
main(int argc, char *argv[])
{
    int sock;
    struct ifreq ifreq;

    sock = socket(AF_INET6, SOCK_DGRAM, 0);
    bzero(&ifreq, sizeof(struct ifreq));
    strcpy(ifreq.ifr_name, "em0");
    ioctl(sock, SIOCGIFADDR, &ifreq);
    return (0);
}
Comment 1 ru freebsd_committer freebsd_triage 2007-05-24 13:04:30 UTC
On Thu, May 24, 2007 at 01:00:10PM +0200, Fredrik Lindberg wrote:
> The em-driver will panic if one issues a SIOCGIFADDR ioctl to a em-device
> with only an inet6 address configured.
> 
> em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
>         options=18b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWCSUM,TSO4>
>         ether 00:11:25:16:db:58
>         inet6 fe80::211:25ff:fe16:db58%em0 prefixlen 64 scopeid 0x1
>         media: Ethernet autoselect
>         status: no carrier
> 
> Fatal trap 12: page fault while in kernel mode
> cpuid = 0; apic id = 00
> fault virtual address   = 0x306d66
> fault code              = supervisor read, page not present
> instruction pointer     = 0x20:0xc087113b
> stack pointer           = 0x28:0xe63b4b4c
> frame pointer           = 0x28:0xe63b4b7c
> code segment            = base rx0, limit 0xfffff, type 0x1b
>                         = DPL 0, pres 1, def32 1, gran 1
> processor eflags        = interrupt enabled, resume, IOPL = 0
> current process         = 1576 (foo)
> 
> Backtrace
> #9  0xc06ad62b in calltrap () at /usr/src/sys/i386/i386/exception.s:139
> #10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
>     data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
> #11 0xc05e44ff in in6_control (so=0xc46cd318, cmd=3284147200,
>     data=0xc48fcd80 "em0", ifp=0xc3c01c00, td=0xc4227000)
>     at /usr/src/sys/netinet6/in6.c:785
> #12 0xc059f258 in ifioctl (so=0xc46cd318, cmd=3223349537, data=0xc48fcd80 "em0",
>     td=0xc4227000) at /usr/src/sys/net/if.c:1874
> #13 0xc055ae97 in soo_ioctl (fp=0x306d65, cmd=3223349537, data=0xc48fcd80,
>    active_cred=0xc4265700, td=0xc4227000) at /usr/src/sys/kern/sys_socket.c:202
> #14 0xc0555dba in kern_ioctl (td=0xc4227000, fd=3, com=3223349537,
>     data=0xc48fcd80 "em0") at file.h:266
> #15 0xc0555bc5 in ioctl (td=0xc4227000, uap=0xe63b4d00)
>     at /usr/src/sys/kern/sys_generic.c:542
> 
> The offending line is
> (kgdb) f 10
> #10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
>     data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
> 977                     if (ifa->ifa_addr->sa_family == AF_INET) {
> 
> 
This is because SIOCGIFADDR expects a pointer to "struct ifreq"
as an argument and not "struct ifaddr" -- it got broken in rev.
1.119 by yongari@ which shouldn't have touched SIOCGIFADDR at
all.  The fix is simple -- just remove the line that tests for
SIOCGIFADDR, and it will get correctly passed down to ether_ioctl()
later, like it was before rev. 1.119:

%%%
Index: if_em.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v
retrieving revision 1.178
diff -u -p -r1.178 if_em.c
--- if_em.c	23 May 2007 20:41:20 -0000	1.178
+++ if_em.c	24 May 2007 11:57:41 -0000
@@ -973,7 +973,6 @@ em_ioctl(struct ifnet *ifp, u_long comma
 
 	switch (command) {
 	case SIOCSIFADDR:
-	case SIOCGIFADDR:
 		if (ifa->ifa_addr->sa_family == AF_INET) {
 			/*
 			 * XXX
%%%

Thanks for the report!


Cheers,
-- 
Ruslan Ermilov
ru@FreeBSD.org
FreeBSD committer
Comment 2 jfvogel 2007-05-24 16:34:00 UTC
On 5/24/07, Ruslan Ermilov <ru@freebsd.org> wrote:
> On Thu, May 24, 2007 at 01:00:10PM +0200, Fredrik Lindberg wrote:
> > The em-driver will panic if one issues a SIOCGIFADDR ioctl to a em-device
> > with only an inet6 address configured.
> >
> > em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
> >         options=18b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWCSUM,TSO4>
> >         ether 00:11:25:16:db:58
> >         inet6 fe80::211:25ff:fe16:db58%em0 prefixlen 64 scopeid 0x1
> >         media: Ethernet autoselect
> >         status: no carrier
> >
> > Fatal trap 12: page fault while in kernel mode
> > cpuid = 0; apic id = 00
> > fault virtual address   = 0x306d66
> > fault code              = supervisor read, page not present
> > instruction pointer     = 0x20:0xc087113b
> > stack pointer           = 0x28:0xe63b4b4c
> > frame pointer           = 0x28:0xe63b4b7c
> > code segment            = base rx0, limit 0xfffff, type 0x1b
> >                         = DPL 0, pres 1, def32 1, gran 1
> > processor eflags        = interrupt enabled, resume, IOPL = 0
> > current process         = 1576 (foo)
> >
> > Backtrace
> > #9  0xc06ad62b in calltrap () at /usr/src/sys/i386/i386/exception.s:139
> > #10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
> >     data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
> > #11 0xc05e44ff in in6_control (so=0xc46cd318, cmd=3284147200,
> >     data=0xc48fcd80 "em0", ifp=0xc3c01c00, td=0xc4227000)
> >     at /usr/src/sys/netinet6/in6.c:785
> > #12 0xc059f258 in ifioctl (so=0xc46cd318, cmd=3223349537, data=0xc48fcd80 "em0",
> >     td=0xc4227000) at /usr/src/sys/net/if.c:1874
> > #13 0xc055ae97 in soo_ioctl (fp=0x306d65, cmd=3223349537, data=0xc48fcd80,
> >    active_cred=0xc4265700, td=0xc4227000) at /usr/src/sys/kern/sys_socket.c:202
> > #14 0xc0555dba in kern_ioctl (td=0xc4227000, fd=3, com=3223349537,
> >     data=0xc48fcd80 "em0") at file.h:266
> > #15 0xc0555bc5 in ioctl (td=0xc4227000, uap=0xe63b4d00)
> >     at /usr/src/sys/kern/sys_generic.c:542
> >
> > The offending line is
> > (kgdb) f 10
> > #10 0xc087113b in em_ioctl (ifp=0xc3c01c00, command=3223349537,
> >     data=0xc48fcd80 "em0") at /usr/src/sys/modules/em/../../dev/em/if_em.c:977
> > 977                     if (ifa->ifa_addr->sa_family == AF_INET) {
> >
> >
> This is because SIOCGIFADDR expects a pointer to "struct ifreq"
> as an argument and not "struct ifaddr" -- it got broken in rev.
> 1.119 by yongari@ which shouldn't have touched SIOCGIFADDR at
> all.  The fix is simple -- just remove the line that tests for
> SIOCGIFADDR, and it will get correctly passed down to ether_ioctl()
> later, like it was before rev. 1.119:
>
> %%%
> Index: if_em.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v
> retrieving revision 1.178
> diff -u -p -r1.178 if_em.c
> --- if_em.c     23 May 2007 20:41:20 -0000      1.178
> +++ if_em.c     24 May 2007 11:57:41 -0000
> @@ -973,7 +973,6 @@ em_ioctl(struct ifnet *ifp, u_long comma
>
>         switch (command) {
>         case SIOCSIFADDR:
> -       case SIOCGIFADDR:
>                 if (ifa->ifa_addr->sa_family == AF_INET) {
>                         /*
>                          * XXX
> %%%
>
> Thanks for the report!

Let me look over the code history a bit, I will try to get a fix
in shortly.

Jack
Comment 3 Mark Linimon freebsd_committer freebsd_triage 2007-05-24 19:53:38 UTC
Responsible Changed
From-To: freebsd-bugs->jfv

jfv is reportedly looking at this.
Comment 4 Sean Bruno freebsd_committer freebsd_triage 2015-06-29 17:53:00 UTC
The problematic commit/code was removed and is no longer an issue in the upcoming 10.2r release.