arm/185617: 10.0-RC1, armv6: "pfctl -s state" crashes on BeagleBone Black due to unaligned access
Guy Yur
guyyur at gmail.com
Thu Jan 9 21:40:03 UTC 2014
>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 at 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:
More information about the freebsd-arm
mailing list