systemd-networkd crashes with SIGSEGV
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
Ubuntu Pro | Status tracked in 18.04 | |||||
18.04 |
Fix Released
|
Medium
|
Tiago Pasqualini da Silva | |||
systemd |
Fix Released
|
Undecided
|
Unassigned | |||
systemd (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
[ Impact ]
Customer reported that this issue happens randomly during their automated regression runs. It's not consistent and hard to reproduce. They have shared a coredump:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000555962aa1c34 in link_drop_
2741 ../src/
(gdb) bt
#0 0x0000555962aa1c34 in link_drop_
#1 0x0000555962aa233d in link_carrier_
#2 0x0000555962a8e9b2 in link_update (m=0x5559635702c0, link=<optimized out>) at ../src/
#3 manager_
#4 0x0000555962a48a16 in process_match (m=0x5559635702c0, rtnl=0x55596355
#5 process_running (ret=0x0, rtnl=0x55596355
#6 sd_netlink_process (rtnl=0x5559635
#7 0x0000555962a48cb3 in time_callback (s=<optimized out>, usec=<optimized out>, userdata=<optimized out>) at ../src/
#8 0x0000555962a4dbae in source_dispatch (s=s@entry=
#9 0x0000555962a4de2a in sd_event_dispatch (e=<optimized out>, e@entry=
#10 0x0000555962a4dfb9 in sd_event_run (e=<optimized out>, e@entry=
#11 0x0000555962a4e1fb in sd_event_loop (e=<optimized out>) at ../src/
#12 0x0000555962a223d6 in main (argc=<optimized out>, argv=<optimized out>) at ../src/
This can be fixed by simply null checking link->network before doing anything with it. Upstream has fixed it on this commit: https:/
[ Test Plan ]
Since this issue is hard to reproduce, I was able trigger it on gdb, by adding a breakpoint once the manager is setup, getting the loopback device and running link_drop_
(gdb) b src/network/
Breakpoint 1 at 0x2f38f: file ../src/
(gdb) r
Starting program: /lib/systemd/
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_
eth0: IPv6 successfully enabled
eth0: Gained IPv6LL
Breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at ../src/
152 log_info(
(gdb) p *m->links
$1 = {b = {hash_ops = 0x55555578f230 <trivial_hash_ops>, {indirect = {storage = 0x2e, hash_key = "\200\376yUUU\
n_entries = 1434074992, n_buckets = 21845, idx_lowest_entry = 256, _pad = "\000\000"}, direct = {
storage = ".\000\
type = HASHMAP_TYPE_PLAIN, has_indirect = false, n_direct_entries = 2, from_pool = true}}
(gdb) set $mylink = (Link **) malloc(sizeof(Link *))
(gdb) call link_get(m, 1, $mylink)
$2 = 0
(gdb) p *$mylink
$3 = (Link *) 0x5555557a3f70
(gdb) p **$mylink
$4 = {manager = 0x555555796940, n_ref = 2, ifindex = 1, master_ifindex = 0, ifname = 0x5555557a0060 "lo", kind = 0x0, iftype = 772,
state_file = 0x55555579c670 "/run/systemd/
__u6_addr8 = '\000' <repeats 15 times>, __u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}}, mtu = 65536, udev_device = 0x0,
flags = 65609, kernel_operstate = 0 '\000', network = 0x0, state = LINK_STATE_
address_
addresses = 0x0, addresses_foreign = 0x555555796120, routes = 0x0, routes_foreign = 0x555555796180, addresses_
addresses_ready = false, dhcp_client = 0x0, dhcp_lease = 0x0, lease_file = 0x55555579c620 "/run/systemd/
dhcp4_messages = 0, dhcp4_configured = false, dhcp6_configured = false, ndisc_messages = 0, ndisc_configured = false, ipv4ll = 0x0,
ipv4ll_address = false, ipv4ll_route = false, static_
setting_genmode = false, ipv6_mtu_set = false, pool_addresses = 0x0, dhcp_server = 0x0, ndisc = 0x0, ndisc_rdnss = 0x0, ndisc_dnssl = 0x0, radv = 0x0,
dhcp6_client = 0x0, rtnl_extended_attrs = true, lldp = 0x0, lldp_file = 0x55555579c6d0 "/run/systemd/
lldp_
(gdb) call link_drop_
Program received signal SIGSEGV, Segmentation fault.
0x00005555554aec34 in link_drop_
warning: Source file is more recent than executable.
2741 } else if (FLAGS_
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(link_drop_
When the function is done executing, GDB will silently stop.
After applying the patch, the issue does not happen:
(gdb) call link_drop_
$10 = 0
[ Where problems could occur ]
This fix implements a simple null check on a pointer before accessing its contents, so it does not impose any risks of regressions.
affects: | netplan → systemd |
Changed in systemd: | |
assignee: | nobody → Tiago Pasqualini da Silva (tiago.pasqualini) |
Changed in systemd (Ubuntu): | |
milestone: | none → bionic-updates |
milestone: | bionic-updates → none |
information type: | Public → Private |
information type: | Private → Public |
description: | updated |
tags: | added: se-sponsor-halves |
description: | updated |
Thank you for the bug report, Thiago! I did a little bit of housekeeping so that this LP accurately reflects this targeting Ubuntu Pro 18.04.
Could you please fill in the description according to the SRU template?
https:/ /wiki.ubuntu. com/StableRelea seUpdates# SRU_Bug_ Template