netlink: fix accessing freed memory

The check for if_addrlen in dump_iface() is not sufficient to determine
if we still have a valid if_addr.  Rather than directly accessing if_addr
check the STAILQ (for the first entry).
This avoids panics when destroying cloned interfaces as experienced with
net80211 wlan ones.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	jhibbits (earlier version), kp
Differential Revision: https://reviews.freebsd.org/D42027
This commit is contained in:
Bjoern A. Zeeb 2023-09-30 15:11:57 +00:00
parent 8b622172ba
commit 7d48224073

View file

@ -292,6 +292,7 @@ static bool
dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
int if_flags_mask)
{
struct epoch_tracker et;
struct ifinfomsg *ifinfo;
NL_LOG(LOG_DEBUG3, "dumping interface %s data", if_name(ifp));
@ -321,11 +322,15 @@ dump_iface(struct nl_writer *nw, if_t ifp, const struct nlmsghdr *hdr,
nlattr_add_u8(nw, IFLA_PROTO_DOWN, val);
nlattr_add_u8(nw, IFLA_LINKMODE, val);
*/
if (if_getaddrlen(ifp) != 0) {
struct ifaddr *ifa = if_getifaddr(ifp);
if (if_getaddrlen(ifp) != 0) {
struct ifaddr *ifa;
dump_sa(nw, IFLA_ADDRESS, ifa->ifa_addr);
}
NET_EPOCH_ENTER(et);
ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
if (ifa != NULL)
dump_sa(nw, IFLA_ADDRESS, ifa->ifa_addr);
NET_EPOCH_EXIT(et);
}
if ((if_getbroadcastaddr(ifp) != NULL)) {
nlattr_add(nw, IFLA_BROADCAST, if_getaddrlen(ifp),