From fdca5fa70c22e790ed9fa714d433f0800f632a59 Mon Sep 17 00:00:00 2001
References: https://github.com/openSUSE/wicked/pull/821
Upstream: Merged
From: Marius Tomaschewski <mt@suse.de>
Date: Wed, 22 Jan 2020 12:18:21 +0100
Subject: [PATCH 1/3] Squashed misc bug fixes from pull#821

https://github.com/openSUSE/wicked/pull/821:

commit 98c0115e5e8b0db84752e5eb81a2b1abbae58618
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Mon Jan 13 14:38:57 2020 +0100

    force aligned struct accesses

commit de2bce5efb6cd5f32a26ce8ef3adc52ebac605f6
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Mon Jan 13 14:00:20 2020 +0100

    ni_iaid_create_hwaddr: deal correctly with unaligned memory

commit ebd4f30689f89ef008675102d9539332b89925de
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 16:37:18 2020 +0100

    turn signed shifts into unsigned shifts: undefined behaviour

commit dc449aacecdd36bc797e5d808bb24b1bf30317b1
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 14:56:00 2020 +0100

    hostname lookup: don't use shellcmd after freeing it

    the process keeps a reference to it, so this was no uaf before. This
    way it's more robust to changes in ni_process_new at least.

commit 11866ee000cadc1c950ed7883edaf5f56187203e
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 14:54:34 2020 +0100

    fix use-after-free in timer

commit d0aa2afa319ff76b2f866316fafe76630d1723d3
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 14:11:15 2020 +0100

    ni_dhcp4_fsm_arp_validate: handle failure to create ARP handle

commit e9a9520142f0aa37398fbbd4c829b6e825b71f1e
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 14:00:02 2020 +0100

    buffer: remove 0-byte memcpy undefined behaviour

commit 8ac6ffcc70e55b19e2ff6f5e4b748bf6a66734cc
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:50:03 2020 +0100

    ni_rule_print: remove superfluous format argument

commit 9b76473e0504e3ab1e4de4d3292e5cc9acbdd201
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:48:46 2020 +0100

    process_run_info: fix check for signal termination

commit c9ce47dbc8bca88f59d07c3078f9f414df8b97c4
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:47:16 2020 +0100

    ni_ifworker_netif_resolve_cb: initalize cwtype variable

commit 5d3d74458b7e1c4ae9060805994b4c270017f571
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:45:00 2020 +0100

    __ni_objectmodel_route_nexthop_from_dict: do not print uninitalized var

commit fed802e40cf51823890bac1cb7f7d617bd23af18
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:44:00 2020 +0100

    ni_config_parse_addrconf_dhcp6_nodes: fix length parsing

commit b25f199ba117d6b333c808165be979073f03f556
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:42:36 2020 +0100

    ni_auto6_on_nduseropt_events: initialize changed variable

commit 3aef8af62ae556ed6bf702eb085209e6dc80cf06
Author: Malte Kraus <malte.kraus@suse.com>
Date:   Fri Jan 10 13:41:38 2020 +0100

    client: format hostnames correctly
---
 client/main.c           |  2 ++
 src/auto6.c             |  2 +-
 src/buffer.c            |  3 ++-
 src/config.c            |  2 +-
 src/dbus-objects/misc.c |  2 +-
 src/dbus-xml.c          |  2 +-
 src/dhcp4/fsm.c         |  2 +-
 src/dhcp6/protocol.c    | 18 +++++++++---------
 src/fsm.c               |  2 +-
 src/iaid.c              |  5 ++---
 src/macvlan.c           |  2 +-
 src/names.c             | 12 ++++++------
 src/netinfo_priv.h      |  2 +-
 src/process.c           |  2 +-
 src/route.c             |  2 +-
 src/timer.c             |  2 +-
 src/update.c            |  2 +-
 src/util.c              |  8 ++++----
 18 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/client/main.c b/client/main.c
index 4449d91c..03a34d71 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1630,6 +1630,7 @@ do_check(int argc, char **argv)
 				if (opt_dbus_error_file) {
 					write_dbus_error(opt_dbus_error_file,
 							NI_DBUS_ERROR_UNRESOLVABLE_HOSTNAME,
+							"%s",
 							hostname);
 					opt_dbus_error_file = NULL;
 				}
@@ -1651,6 +1652,7 @@ do_check(int argc, char **argv)
 					if (opt_dbus_error_file) {
 						write_dbus_error(opt_dbus_error_file,
 								NI_DBUS_ERROR_UNREACHABLE_ADDRESS,
+								"%s",
 								hostname);
 						opt_dbus_error_file = NULL;
 					}
diff --git a/src/auto6.c b/src/auto6.c
index e349293c..22e0d91a 100644
--- a/src/auto6.c
+++ b/src/auto6.c
@@ -717,7 +717,7 @@ ni_auto6_on_nduseropt_events(ni_netdev_t *dev, ni_event_t event)
 	ni_addrconf_lease_t *lease;
 	unsigned int lifetime;
 	struct timeval now;
-	ni_bool_t changed;
+	ni_bool_t changed = FALSE;
 
 	if (!dev)
 		return;
diff --git a/src/buffer.c b/src/buffer.c
index fe4c7913..adde03dd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -25,7 +25,8 @@ ni_buffer_ensure_tailroom(ni_buffer_t *bp, unsigned int min_room)
 		unsigned char *new_base;
 
 		new_base = xmalloc(new_size);
-		memcpy(new_base, bp->base, bp->size);
+		if (bp->size)
+			memcpy(new_base, bp->base, bp->size);
 		bp->base = new_base;
 		bp->allocated = 1;
 	}
diff --git a/src/config.c b/src/config.c
index ff8b74cf..a11a363a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1147,7 +1147,7 @@ ni_config_parse_addrconf_dhcp6_nodes(ni_config_dhcp6_t *dhcp6, xml_node_t *node)
 				int len;
 
 				/* DUID is "opaque", but has 2 bytes type + up to 128 bytes */
-				if ((len = sizeof(pref->serverid.data)) > 130)
+				if ((len = pref->serverid.len) > 130)
 					len = 130;
 
 				 /* DUID-LL has 2+2 fixed bytes + variable length hwaddress
diff --git a/src/dbus-objects/misc.c b/src/dbus-objects/misc.c
index ed393d97..454b4740 100644
--- a/src/dbus-objects/misc.c
+++ b/src/dbus-objects/misc.c
@@ -1058,7 +1058,7 @@ __ni_objectmodel_route_nexthop_from_dict(ni_route_nexthop_t *nh, const ni_dbus_v
 	 */
 	if (ni_dbus_dict_get(nhdict, "gateway")) {
 		if (!__ni_objectmodel_dict_get_sockaddr(nhdict, "gateway", &nh->gateway)) {
-			ni_debug_dbus("%s: invalid route hop gateway %u", __func__, value);
+			ni_debug_dbus("%s: invalid route hop gateway", __func__);
 			return FALSE;
 		}
 	}
diff --git a/src/dbus-xml.c b/src/dbus-xml.c
index 2e29cdb6..741bf158 100644
--- a/src/dbus-xml.c
+++ b/src/dbus-xml.c
@@ -610,7 +610,7 @@ ni_dbus_serialize_xml_bitmap(const xml_node_t *node, const ni_xs_scalar_info_t *
 
 		/* May left shift past width of value if bb >= 32, but as ret
 		 * will be FALSE assignment to result will not happen. */
-		value |= 1 << bb;
+		value |= NI_BIT(bb);
 	}
 
 	ni_string_array_destroy(&bit_name_arr);
diff --git a/src/dhcp4/fsm.c b/src/dhcp4/fsm.c
index 3b55b074..89c9148f 100644
--- a/src/dhcp4/fsm.c
+++ b/src/dhcp4/fsm.c
@@ -1070,7 +1070,7 @@ ni_dhcp4_fsm_arp_validate(ni_dhcp4_device_t *dev)
 	if (dev->arp.handle == NULL) {
 		dev->arp.handle = ni_arp_socket_open(&dev->system,
 				ni_dhcp4_fsm_process_arp_packet, dev);
-		if (!dev->arp.handle->user_data) {
+		if (!dev->arp.handle || !dev->arp.handle->user_data) {
 			ni_error("%s: unable to create ARP handle", dev->ifname);
 			return -1;
 		}
diff --git a/src/dhcp6/protocol.c b/src/dhcp6/protocol.c
index d8d6c2a3..1e1ef81d 100644
--- a/src/dhcp6/protocol.c
+++ b/src/dhcp6/protocol.c
@@ -354,7 +354,6 @@ ni_dhcp6_socket_recv(ni_socket_t *sock)
 static int
 ni_dhcp6_process_packet(ni_dhcp6_device_t *dev, ni_buffer_t *msgbuf, const struct in6_addr *sender)
 {
-	ni_dhcp6_packet_header_t *header;
 	ni_dhcp6_message_t msg;
 	int rv = -1;
 
@@ -376,8 +375,8 @@ ni_dhcp6_process_packet(ni_dhcp6_device_t *dev, ni_buffer_t *msgbuf, const struc
 	/*
 	 * peek header only
 	 */
-	header = ni_buffer_head(msgbuf);
-	switch(header->type) {
+	uint8_t *type = ni_buffer_head(msgbuf);
+	switch(*type) {
 		/* handle client response msgs */
 		case NI_DHCP6_ADVERTISE:
 		case NI_DHCP6_REPLY:
@@ -399,7 +398,7 @@ ni_dhcp6_process_packet(ni_dhcp6_device_t *dev, ni_buffer_t *msgbuf, const struc
 		default:
 			ni_debug_dhcp("%s: received %s message in state %s from %s: discarding",
 					dev->ifname,
-					ni_dhcp6_message_name(header->type),
+					ni_dhcp6_message_name(*type),
 					ni_dhcp6_fsm_state_name(dev->fsm.state),
 					ni_dhcp6_address_print(&msg.sender));
 		break;
@@ -3098,15 +3097,16 @@ failure:
 int
 ni_dhcp6_parse_client_header(ni_dhcp6_message_t *msg, ni_buffer_t *msgbuf)
 {
-	ni_dhcp6_client_header_t * header;
+	ni_dhcp6_client_header_t header;
 
 	if (!msgbuf || !msg)
 		return -1;
 
-	header = ni_buffer_pull_head(msgbuf, sizeof(*header));
-	if (header) {
-		msg->type = header->type;
-		msg->xid  = ni_dhcp6_message_xid(header->xid);
+	const char *header_src = ni_buffer_pull_head(msgbuf, sizeof(header));
+	if (header_src) {
+		memcpy(&header, header_src, sizeof(header));
+		msg->type = header.type;
+		msg->xid  = ni_dhcp6_message_xid(header.xid);
 		return 0;
 	}
 	return -1;
diff --git a/src/fsm.c b/src/fsm.c
index f31e6fe6..695b12c3 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -3688,7 +3688,7 @@ ni_ifworker_netif_resolve_cb(xml_node_t *node, const ni_xs_type_t *type, const x
 	ni_ifworker_t *w = closure->worker;
 	ni_ifworker_t *cw = NULL;
 	xml_node_t *cwmeta = NULL;
-	ni_ifworker_type_t cwtype;
+	ni_ifworker_type_t cwtype = NI_IFWORKER_TYPE_NONE;
 	unsigned int requires = 0;
 	xml_node_t *mchild;
 
diff --git a/src/iaid.c b/src/iaid.c
index 234a6492..6fafdf6d 100644
--- a/src/iaid.c
+++ b/src/iaid.c
@@ -445,7 +445,6 @@ ni_iaid_map_del_iaid(ni_iaid_map_t *map, unsigned int iaid)
 ni_bool_t
 ni_iaid_create_hwaddr(unsigned int *iaid, const ni_hwaddr_t *hwa)
 {
-	uint32_t *ptr;
 	size_t off;
 
 	if (!iaid || !hwa)
@@ -458,8 +457,8 @@ ni_iaid_create_hwaddr(unsigned int *iaid, const ni_hwaddr_t *hwa)
 		return FALSE;
 
 	off = hwa->len - sizeof(*iaid);
-	ptr = (uint32_t *)(hwa->data + off);
-	*iaid = ntohl(*ptr);
+	memcpy(iaid, hwa->data + off, sizeof(uint32_t));
+	*iaid = ntohl(*iaid);
 	return TRUE;
 }
 
diff --git a/src/macvlan.c b/src/macvlan.c
index 3f31d6e3..9e89c404 100644
--- a/src/macvlan.c
+++ b/src/macvlan.c
@@ -119,7 +119,7 @@ ni_macvlan_name_to_flag(const char *name, unsigned int *flag)
 const char *
 ni_macvlan_flag_bit_name(unsigned int bit)
 {
-	return bit < 32 ? ni_macvlan_flag_to_name(1 << bit) : NULL;
+	return bit < 32 ? ni_macvlan_flag_to_name(NI_BIT(bit)) : NULL;
 }
 
 ni_bool_t
diff --git a/src/names.c b/src/names.c
index c66a33d2..83164552 100644
--- a/src/names.c
+++ b/src/names.c
@@ -226,16 +226,16 @@ ni_addrconf_flag_bit_set(unsigned int *mask, unsigned int flag, ni_bool_t enable
 {
 	if (mask) {
 		if (enable)
-			*mask |=  (1U << flag);
+			*mask |=  NI_BIT(flag);
 		else
-			*mask &= ~(1U << flag);
+			*mask &= ~NI_BIT(flag);
 	}
 }
 
 ni_bool_t
 ni_addrconf_flag_bit_is_set(unsigned int flags, unsigned int flag)
 {
-	return flags & (1 << flag);
+	return flags & NI_BIT(flag);
 }
 
 const char *
@@ -288,9 +288,9 @@ ni_addrconf_update_set(unsigned int *mask, unsigned int flag, ni_bool_t enable)
 {
 	if (mask) {
 		if (enable)
-			*mask |= (1 << flag);
+			*mask |= NI_BIT(flag);
 		else
-			*mask &= ~(1 << flag);
+			*mask &= ~NI_BIT(flag);
 	}
 }
 
@@ -690,7 +690,7 @@ ni_linkflags_bit_to_name(unsigned int bit)
 {
 	if (bit >= 32)
 		return NULL;
-	return ni_format_uint_mapped(1 << bit, __ni_linkifflag_names);
+	return ni_format_uint_mapped(NI_BIT(bit), __ni_linkifflag_names);
 }
 
 const char *
diff --git a/src/netinfo_priv.h b/src/netinfo_priv.h
index ee82782c..644e520a 100644
--- a/src/netinfo_priv.h
+++ b/src/netinfo_priv.h
@@ -122,7 +122,7 @@ extern int		__ni_wireless_link_event(ni_netconfig_t *, ni_netdev_t *, void *, si
 
 static inline ni_bool_t	__ni_addrconf_should_update(unsigned int mask, unsigned int bit)
 {
-	return !!(mask & (1 << bit));
+	return !!(mask & NI_BIT(bit));
 }
 
 /*
diff --git a/src/process.c b/src/process.c
index 56518800..156eb125 100644
--- a/src/process.c
+++ b/src/process.c
@@ -402,7 +402,7 @@ __ni_process_run_info(ni_process_t *pi)
 				pi->pid, pi->process->command, rv, runtime);
 		return rv;
 	} else
-	if ((rv = ni_process_signaled(pi)) != NI_PROCESS_FAILURE) {
+	if ((rv = ni_process_term_signal(pi)) != NI_PROCESS_FAILURE) {
 		ni_debug_extension("subprocess %d (%s) died with signal %d%s%s",
 				pi->pid, pi->process->command, rv,
 				ni_process_core_dumped(pi) ? " (core dumped)" : "",
diff --git a/src/route.c b/src/route.c
index 2f69e32d..4ee612ce 100644
--- a/src/route.c
+++ b/src/route.c
@@ -2197,7 +2197,7 @@ ni_rule_print(ni_stringbuf_t *out, const ni_rule_t *rule)
 		ni_stringbuf_printf(out, " pref auto");
 
 	if (rule->flags & NI_BIT(NI_RULE_INVERT))
-		ni_stringbuf_printf(out, " not", rule->pref);
+		ni_stringbuf_printf(out, " not");
 
 	if (rule->src.len)
 		ni_stringbuf_printf(out, " from %s/%u",
diff --git a/src/timer.c b/src/timer.c
index db5f1f31..abff61e1 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -52,9 +52,9 @@ ni_timer_cancel(const ni_timer_t *handle)
 
 	if ((timer = __ni_timer_disarm(handle)) != NULL) {
 		user_data = timer->user_data;
-		free(timer);
 		ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_TIMER,
 				"%s: released timer %p", __func__, timer);
+		free(timer);
 	} else {
 		ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_TIMER,
 				"%s: timer %p NOT found", __func__, handle);
diff --git a/src/update.c b/src/update.c
index 14e589f3..a33fc97a 100644
--- a/src/update.c
+++ b/src/update.c
@@ -1528,7 +1528,7 @@ ni_system_updater_hostname_lookup_call(ni_updater_t *updater, ni_updater_job_t *
 				ni_addrconf_type_to_name(job->lease->type),
 				ni_addrconf_state_to_name(job->lease->state),
 				ni_updater_name(job->kind),
-				ni_basename(shellcmd->command), pi->pid);
+				ni_basename(pi->process->command), pi->pid);
 	} else {
 		ni_process_free(pi);
 	}
diff --git a/src/util.c b/src/util.c
index 74d0dcc8..beea242d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -805,7 +805,7 @@ ni_bitfield_setbit(ni_bitfield_t *bf, unsigned int bit)
 {
 	if (!bf || !ni_bitfield_grow(bf, bit))
 		return FALSE;
-	bf->field[bit / 32] |= (1 << (bit % 32));
+	bf->field[bit / 32] |= NI_BIT(bit % 32u);
 	return TRUE;
 }
 
@@ -814,7 +814,7 @@ ni_bitfield_clearbit(ni_bitfield_t *bf, unsigned int bit)
 {
 	if (!bf || !ni_bitfield_grow(bf, bit))
 		return FALSE;
-	bf->field[bit / 32] &= ~(1 << (bit % 32));
+	bf->field[bit / 32] &= ~NI_BIT(bit % 32u);
 	return TRUE;
 }
 
@@ -832,7 +832,7 @@ ni_bitfield_testbit(const ni_bitfield_t *bf, unsigned int bit)
 {
 	if (!bf || bit / 32 >= bf->size)
 		return FALSE;
-	return !!(bf->field[bit / 32] & (1 << (bit % 32)));
+	return !!(bf->field[bit / 32] & NI_BIT(bit % 32u));
 }
 
 ni_bool_t
@@ -1807,7 +1807,7 @@ ni_format_bitmap(ni_stringbuf_t *buf, const ni_intmap_t *map,
 		sep = "|";
 
 	for (i = 0; map->name; ++map) {
-		flag = (1 << map->value);
+		flag = NI_BIT(map->value);
 		if (flags & flag) {
 			flags &= ~flag;
 			if (i++)
-- 
2.16.4

