Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unaligned 32-bit reads following casts on dns_socket_dispatcher::local_addr (Cortex-M0) #77188

Closed
IWillDonut opened this issue Aug 17, 2024 · 4 comments · Fixed by #77376
Closed
Assignees
Labels
area: Networking bug The issue is a bug, or the PR is fixing a bug platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) priority: low Low impact/importance bug

Comments

@IWillDonut
Copy link

Describe the bug

dns_socket_dispatcher::local_addr is not aligned for the 32-bit read of local_addr.sin_addr.s_addr in net_context_bind() leading to a hard-fault on a Cortex-M0. I've noticed this for the IPv4 path, but I suspect this impacts other paths in net_context_bind() as well.

I've been able to get around with either of the two workarounds:

(a) Forcing the alignment of dns_socket_dispatcher::local_addr to the maximum alignment of the various address types resolves the issue.

(b) Updating net_context_bind() to use the unaligned helpers from net_ip.h.

To Reproduce

Apologies, I'm fairly new and not sure if there's a way to reproduce this in QEMU, so the following assumes access to the physical hardware.

Add the board files from Additional context below to samples/net/dhcpv4_client/boards.

west build -b rpi_pico samples/net/dhcpv4_client --pristine
west debug

Set a breakpoint for the faulting instruction:

b zephyr/subsys/net/ip/net_context.c:868

The following ldr tries to perform an unaligned read from address 0x200015E2 leading to the hard-fault shown below:

0x1000c1a0 <net_context_bind+92>        ldr     r2, [r5, #4]

# r5             0x200015de

Expected behavior

No hard faults in DNS path.

Impact

Unable to use DNS (and DHCP) on my board.

Logs and console output

[00:00:03.348,000] <err> os: ***** HARD FAULT *****
[00:00:03.348,000] <err> os: r0/a1:  0x00000000  r1/a2:  0x20001eee  r2/a3:  0x00000000
[00:00:03.348,000] <err> os: r3/a4:  0xe0000000 r12/ip:  0x2b4be420 r14/lr:  0x100169e3
[00:00:03.348,000] <err> os:  xpsr:  0x61000000
[00:00:03.348,000] <err> os: Faulting instruction address (r15/pc): 0x10016a1c
[00:00:03.348,000] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
[00:00:03.348,000] <err> os: Current thread: 0x20001ca8 (rx_q[0])
[00:00:03.396,000] <err> os: Halting system
#0  net_context_bind (context=context@entry=0x20001ff8 <contexts>, addr=0x200015de <dns_default_ctx+30>, addrlen=<optimized out>) at zephyr/subsys/net/ip/net_context.c:868
#1  0x10005cfc in zsock_bind_ctx (ctx=0x20001ff8 <contexts>, addr=<optimized out>, addrlen=<optimized out>) at zephyr/subsys/net/lib/sockets/sockets.c:478
#2  0x100174ce in sock_bind_vmeth (obj=<optimized out>, addr=<optimized out>, addrlen=<optimized out>) at zephyr/subsys/net/lib/sockets/sockets.c:3852
#3  0x10005d72 in z_impl_zsock_bind (sock=<optimized out>, addr=addr@entry=0x200015de <dns_default_ctx+30>, addrlen=8) at zephyr/subsys/net/lib/sockets/sockets.c:497
#4  0x1000ef6e in zsock_bind (addrlen=<optimized out>, addr=0x200015de <dns_default_ctx+30>, sock=<optimized out>) at zephyr/build/zephyr/include/generated/zephyr/syscalls/socket.h:158
#5  dns_dispatcher_register (ctx=ctx@entry=0x200015d0 <dns_default_ctx+16>) at zephyr/subsys/net/lib/dns/dispatcher.c:247
#6  0x1000f1dc in register_dispatcher (svc=0x1001bc10 <resolve_svc>, addr6=0x0, addr4=<optimized out>, local=0x20003d68 <rx_stack+1064>, server=0x200015c0 <dns_default_ctx>, ctx=0x200015c0 <dns_default_ctx>) at zephyr/subsys/net/lib/dns/resolve.c:317
#7  dns_resolve_init_locked (ctx=ctx@entry=0x200015c0 <dns_default_ctx>, servers=servers@entry=0x0, servers_sa=servers_sa@entry=0x20003de8 <rx_stack+1192>) at zephyr/subsys/net/lib/dns/resolve.c:475
#8  0x1001a1de in dns_resolve_reconfigure (ctx=0x200015c0 <dns_default_ctx>, servers=servers@entry=0x0, servers_sa=0x20003de8 <rx_stack+1192>, servers_sa@entry=0x20003e28 <rx_stack+1256>) at zephyr/subsys/net/lib/dns/resolve.c:1617
#9  0x1000e778 in dhcpv4_parse_options (msg_type=<synthetic pointer>, iface=0x200008d8 <__net_if_dts_ord_74_0>, pkt=0x200081ac <_k_mem_slab_buf_rx_pkts+60>) at zephyr/subsys/net/lib/dhcpv4/dhcpv4.c:1110
#10 net_dhcpv4_input (conn=<optimized out>, pkt=0x200081ac <_k_mem_slab_buf_rx_pkts+60>, ip_hdr=0x200008d8 <__net_if_dts_ord_74_0>, proto_hdr=<optimized out>, user_data=0x0) at zephyr/subsys/net/lib/dhcpv4/dhcpv4.c:1534
#11 0x1000d60a in net_conn_input (pkt=pkt@entry=0x200081ac <_k_mem_slab_buf_rx_pkts+60>, ip_hdr=ip_hdr@entry=0x20003e94 <rx_stack+1364>, proto=<optimized out>, proto_hdr=proto_hdr@entry=0x20003e90 <rx_stack+1360>) at zephyr/subsys/net/ip/connection.c:919
#12 0x10019aba in net_ipv4_input (pkt=pkt@entry=0x200081ac <_k_mem_slab_buf_rx_pkts+60>, is_loopback=is_loopback@entry=false) at zephyr/subsys/net/ip/ipv4.c:437
#13 0x10017c6a in process_data (is_loopback=<optimized out>, pkt=0x200081ac <_k_mem_slab_buf_rx_pkts+60>) at zephyr/subsys/net/ip/net_core.c:138
#14 processing_data (pkt=0x200081ac <_k_mem_slab_buf_rx_pkts+60>, is_loopback=<optimized out>) at zephyr/subsys/net/ip/net_core.c:156
#15 0x10017e6c in net_rx (iface=<optimized out>, pkt=<optimized out>) at zephyr/subsys/net/ip/net_core.c:452
#16 net_process_rx_packet (pkt=<optimized out>) at zephyr/subsys/net/ip/net_core.c:464
#17 0x10019226 in tc_rx_handler (p1=0x200014b8 <rx_classes>, p2=<optimized out>, p3=<optimized out>) at zephyr/subsys/net/ip/net_tc.c:257
#18 0x10001930 in z_thread_entry (entry=0x1001920b <tc_rx_handler>, p1=0x200014b8 <rx_classes>, p2=0x0, p3=0x0) at zephyr/lib/os/thread_entry.c:48

Environment:

  • OS: Windows
  • Toolchain: Zephyr SDK
  • Commit SHA: 15aab68
  • Board: rpi-pico
  • Ethernet Controller: enc28j60

Additional context

boards/rpi_pico.conf

CONFIG_SPI=y
CONFIG_ETH_DRIVER=y
CONFIG_ETH_ENC28J60=y
CONFIG_NET_L2_ETHERNET=y

boards/rpi_pico.overlay

&spi0 {
	status = "okay";
	pinctrl-names = "default";
	cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
	clock-frequency = <4000000>;

	eth_enc28j60: eth_enc28j60@0 {
		compatible = "microchip,enc28j60";
		reg = <0x0>;
		spi-max-frequency = <2000000>;
		label = "ETH_0";
		local-mac-address = [b8 27 eb d2 ec 5c];
		int-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
	};
};

&pinctrl {
	spi0_default: spi0_default {
		group1 {
			pinmux = <SPI0_CSN_P5>, <SPI0_SCK_P2>, <SPI0_TX_P3>;
		};
		group2 {
			pinmux = <SPI0_RX_P4>;
			input-enable;
		};
	};
};
@IWillDonut IWillDonut added the bug The issue is a bug, or the PR is fixing a bug label Aug 17, 2024
Copy link

Hi @IWillDonut! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

@jukkar
Copy link
Member

jukkar commented Aug 18, 2024

(b) Updating net_context_bind() to use the unaligned helpers from net_ip.h.

This sounds like a proper way, could you send a PR for it?

@jukkar
Copy link
Member

jukkar commented Aug 20, 2024

There was a similar report discussed in #77184. Would either @IWillDonut or @hulryung be able to send a PR to fix this?

@dkalowsk dkalowsk added priority: low Low impact/importance bug platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) labels Aug 20, 2024
@IWillDonut
Copy link
Author

Sure thing. I can take a look at getting a PR up for this later this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Networking bug The issue is a bug, or the PR is fixing a bug platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) priority: low Low impact/importance bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants