Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 09 Jan 2014 23:37:21 +0200
From:      Guy Yur <guyyur@gmail.com>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   arm/185617: 10.0-RC1, armv6: "pfctl -s state" crashes on BeagleBone Black due to unaligned access
Message-ID:  <52cf16b1.45b00e0a.3aa5.ffff8053@mx.google.com>
Resent-Message-ID: <201401092140.s09Le2Iu037915@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         185617
>Category:       arm
>Synopsis:       10.0-RC1, armv6: "pfctl -s state" crashes on BeagleBone Black due to unaligned access
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-arm
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jan 09 21:40:02 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator:     Guy Yur
>Release:        FreeBSD 10.0-RC1 arm
>Organization:
>Environment:
System: FreeBSD bbb.localdomain 10.0-RC1 FreeBSD 10.0-RC1 #1 r259250M: Thu Dec 12 22:54:08 IST 2013     root@vm8.localdomain:/usr/obj/arm.armv6/usr/src/sys/BBB  arm


>Description:
I am running 10.0-RC1 arm.armv6 on the BeagleBone Black.
The "pfctl -s state" command is crashing when trying to print the
second entry.

struct pfsync_state has a size that is not divisiable by 4 leading to the
second entry in the returned state array not being aligned.  This is fine when
accessing the entry as a struct pfsync_state pointer since the struct has the
__packed attribute and on arm unaligned access will be used.  When print_host
is called it receives a pf_addr struct pointer &nk->addr[1] which is not
aligned on 4 bytes for the second entry and since the struct is not __packed
it will be accessed using word load instructions which will trigger an
unaligned access fault and pfctl will exit with bus error.

(gdb) bt
#0  print_host (addr=0x2085a11a, port=7660, af=2 '\002', opts=1024) at /usr/src/sbin/pfctl/pf_print_state.c:178
#1  0x00021c4c in print_state (s=0x2085a0f2, opts=1024) at /usr/src/sbin/pfctl/pf_print_state.c:236
#2  0x0000c664 in pfctl_show_states (dev=<value optimized out>, iface=0x0, opts=1024) at /usr/src/sbin/pfctl/pfctl.c:1095

sizeof(struct pfsync_state_key) is 36
sizeof(struct pfsync_state_peer) is 32
sizeof(struct pf_addr) is 16
sizeof(struct pfsync_state) is 242


>How-To-Repeat:
pf running on an arm host, make sure there is more than one active connection.
Run: pfctl -s state

>Fix:

A quick workaround is for print_state to copy the pf_addr in pfsync_state_key
to a pf_addr struct on the stack and pass it to print_host.

Another possibility is to make sure pfsync_state is aligned on at least
4 bytes (8 preferred for the u_int64_t id) or create a new aligned struct
for the DIOCGETSTATE and DIOCGETSTATES ioctls to separate between the
pfsync_state as protocol data and the info returned by the ioctls.
Changing pfsync_state size will break KBI and the pfsync protocol.
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?52cf16b1.45b00e0a.3aa5.ffff8053>