NetBSD Problem Report #49020

From t.hash425@gmail.com  Fri Jul 18 21:23:20 2014
Return-Path: <t.hash425@gmail.com>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 0C029A5675
	for <gnats-bugs@gnats.netbsd.org>; Fri, 18 Jul 2014 21:23:20 +0000 (UTC)
Message-Id: <53C99043.7060104@gmail.com>
Date: Sat, 19 Jul 2014 06:23:15 +0900
From: Takahiro HAYASHI <t.hash425@gmail.com>
To: gnats-bugs@gnats.NetBSD.org
Subject: Writing to tap device may cause panic on RPI

>Number:         49020
>Category:       port-evbarm
>Synopsis:       Writing to tap device may cause panic on RPI
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-evbarm-maintainer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jul 18 21:25:00 +0000 2014
>Closed-Date:    Tue Sep 02 11:41:35 +0000 2014
>Last-Modified:  Tue Sep 02 11:41:35 +0000 2014
>Originator:     Takahiro HAYASHI
>Release:        NetBSD 6.99.47 2014-07-18 11:57:12 UTC
>Organization:
>Environment:
System: NetBSD raspi 6.99.47 NetBSD 6.99.47 (MYRPI) #13: Fri Jul 18 20:50:08 JST 2014  root@halt:/build/head/obj.evbarm/sys/arch/evbarm/compile/MYRPI evbarm
Architecture: earmhf
Machine: evbarm
>Description:
	Writing to tap device may cause panic on Raspberry-Pi.

	tap(4) needs to be written data with ethernet link-level header,
	whose length is 14.  It means payload is not aligned.
	ip6_input() tries to adjust alignment but does not do because
	__NO_STRICT_ALIGNMENT is defined in arm/types.h on RPI.
	This causes ip6->ip6_dst not aligned and copying struct
	> sin6->sin6_addr = *addr;
	in sockaddr_in6_init1() (this is inline func in in6.h) fails.

# ./a.out
writing data 0x212e0 len 70 to tap0 (f2:0b:a4:61:b0:fb)
data_abort_handler: data_aborts fsr=0x1 far=0xdbf1fa5e
Fatal kernel mode data abort: 'Alignment Fault 1'
trapframe: 0xdbf2be98
FSR=00000001, FAR=dbf1fa5e, spsr=80000013
r0 =00000000, r1 =00000000, r2 =00000018, r3 =0000001c
r4 =c0489444, r5 =00000000, r6 =dbf1fa46, r7 =dbf1fa5e
r8 =dbf1fa4e, r9 =00000004, r10=00000010, r11=dbf2bf4c
r12=00000000, ssp=dbf2bee8, slr=dbf2bf0c, pc =c00c4914

Stopped in pid 0.3 (system) at  netbsd:ip6_input+0x7d0: ldmia   r7, {r0-r3}
db> bt
0xdbf2bf4c: netbsd:ip6_input+0xc
0xdbf2bf64: netbsd:ip6intr+0x6c
0xdbf2bfac: netbsd:softint_dispatch+0xec
Bad frame pointer: 0xdb98bd34

>How-To-Repeat:
	Enable tap* devices in your kernel and
	configure tap0 and run this program.
	> ifconfig tap0 create up
	> ./a.out

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <err.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_ether.h>
#include <net/if_tap.h>

static struct ether_addr *getmyenaddr(char *);

/* total_len 0t70 (14+40+16)
  * ether 00:16:3e:00:00:01 -> 0:0:0:0:0:0 (filled later)
  * IP6 (hlim 64, next-header ICMPv6 (58) payload length: 16)
  *   2001:db8::2 > 2001:db8::1: ICMP6, echo reply, seq 0
  */
static uint8_t data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 		/* ether_dhost */
0x00, 0x16, 0x3e, 0x00, 0x00, 0x01, 		/* ether_shost */
0x86, 0xdd,					/* ETHERTYPE_IPV6 */
0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3a, 0x40, /* plen 16 ICMPv6 hlim 64 */
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, /* src */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, /* dst */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x81, 0x00, 0x11, 0x0c, 0x12, 0x34, 0x00, 0x00, /* echo-reply */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int
main(int ac, char **av)
{
	int fd;
	struct ifreq ifr;
	struct ether_addr *ea;

	if ((fd = open("/dev/tap0", O_RDWR, 0)) < 0)
		err(1, "tapopen");

	memset(&ifr, 0, sizeof ifr);
	if (ioctl(fd, TAPGIFNAME, &ifr) != 0)
		err(1, "TAPGIFNAME");

	if ((ea = getmyenaddr(ifr.ifr_name)) == NULL)
		err(1, "getmyenaddr");
	memcpy(&data[0], ea, ETHER_ADDR_LEN);
	printf("writing data %p len %zd to %s (%s)\n",
	    data, sizeof data, ifr.ifr_name, ether_ntoa(ea));
	fflush(stdout);
	usleep(100000);

	write(fd, data, sizeof data);

	close(fd);
}

static struct ether_addr *
getmyenaddr(char *ifname)
{
	struct ifaddrs *ifap0, *ifap;
	struct ether_addr *ea = NULL;
	static struct ether_addr ea0;

	if (getifaddrs(&ifap0) == -1) {
		perror("getifaddrs");
		return NULL;
	}

	for (ifap = ifap0; ifap; ifap = ifap->ifa_next) {
		if (strncmp(ifap->ifa_name, ifname, IFNAMSIZ))
			continue;
		if (ifap->ifa_addr->sa_family != AF_LINK)
			continue;
		ea = (struct ether_addr *)
		    LLADDR((struct sockaddr_dl *)ifap->ifa_addr);
		memcpy(&ea0, ea, sizeof(ea0));
		freeifaddrs(ifap0);
		return &ea0;
	}
	freeifaddrs(ifap0);
	return NULL;
}
__EOF__

>Fix:
	To avoid this issue, comment out __NO_STRICT_ALIGNMENT in types.h.

	Is it a good idea that tap_dev_write() puts data on mbuf
	ETHER_ALIGN (2) bytes later for padding and do m_adj(m, 2) ?

-- 
t-hash

>Release-Note:

>Audit-Trail:
From: Nick Hudson <skrll@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: Takahiro HAYASHI <t.hash425@gmail.com>, 
 port-evbarm-maintainer@netbsd.org, gnats-admin@netbsd.org, 
 netbsd-bugs@netbsd.org
Subject: Re: port-evbarm/49020: Writing to tap device may cause panic on RPI
Date: Mon, 21 Jul 2014 16:57:40 +0100

 This affects beaglebone (armv7) as well.

 Nick

From: "Nick Hudson" <skrll@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/49020 CVS commit: src/sys/arch/arm/include
Date: Tue, 5 Aug 2014 06:24:57 +0000

 Module Name:	src
 Committed By:	skrll
 Date:		Tue Aug  5 06:24:56 UTC 2014

 Modified Files:
 	src/sys/arch/arm/include: types.h

 Log Message:
 Don't set __NO_STRICT_ALIGNMENT as armv[67] ldm/stm have alignment
 restrictions.

 PR/49020: Writing to tap device may cause panic on RPI

 Discussed with matt@


 To generate a diff of this commit:
 cvs rdiff -u -r1.27 -r1.28 src/sys/arch/arm/include/types.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->feedback
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Tue, 05 Aug 2014 06:25:58 +0000
State-Changed-Why:
__NO_STRICT_ALIGNMENT has been removed. OK to close?


From: Takahiro HAYASHI <t.hash425@gmail.com>
To: gnats-bugs@NetBSD.org, port-evbarm-maintainer@netbsd.org, 
 skrll@NetBSD.org
Cc: 
Subject: Re: port-evbarm/49020 (Writing to tap device may cause panic on RPI)
Date: Tue, 05 Aug 2014 18:43:03 +0900

 (08/05/14 15:25), skrll@NetBSD.org wrote:
 > Synopsis: Writing to tap device may cause panic on RPI
 >
 > State-Changed-From-To: open->feedback
 > State-Changed-By: skrll@NetBSD.org
 > State-Changed-When: Tue, 05 Aug 2014 06:25:58 +0000
 > State-Changed-Why:
 > __NO_STRICT_ALIGNMENT has been removed. OK to close?

 Yes.
 I confirmed that the reproducing program
 does not panic my Raspberry-Pi.
 Thank you for fixing the problem.


 -- 
 t-hash

State-Changed-From-To: feedback->closed
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Tue, 02 Sep 2014 11:41:35 +0000
State-Changed-Why:
Problem fixed.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.