diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2023-09-30 15:11:57 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2023-10-05 14:27:10 +0000 |
commit | 7d48224073ce14f0dd3db2d4e96876ac928b52f2 (patch) | |
tree | e6576978ce498f6eaff340c64eac1f735934b532 | |
parent | 8b622172ba44f914092c1d44cecb2b101eb8e17b (diff) |
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
-rw-r--r-- | sys/netlink/route/iface.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index e1939c7681de..b6e120933f83 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -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), |