From 5362aa8ce565554973b282e47084e8b3cacabadb Mon Sep 17 00:00:00 2001 From: Bijan Date: Tue, 1 Feb 2022 11:03:00 +0330 Subject: [PATCH] zebra: Keep the interface flags safe on multiple ioctl calls Trying to call multiple ioctl calls on ifreq will result in overwriting ifreq with garbage data. On if_get_flags call, try to keep the flags field safe from another possible ioctl call before applying the flags field. Modified code as per Code Review, done by Donald Sharp. Signed-off-by: Bijan (cherry picked from commit 16dca7cec5f47b7a6f83822a1e681652b7d2d60d) --- zebra/ioctl.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 8b30eea9f1..9b6aaf1d85 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -410,11 +410,14 @@ int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx) void if_get_flags(struct interface *ifp) { int ret; - struct ifreq ifreq; + struct ifreq ifreqflags; + struct ifreq ifreqdata; - ifreq_set_name(&ifreq, ifp); + ifreq_set_name(&ifreqflags, ifp); + ifreq_set_name(&ifreqdata, ifp); - ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf->vrf_id); + ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreqflags, + ifp->vrf->vrf_id); if (ret < 0) { flog_err_sys(EC_LIB_SYSTEM_CALL, "vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s", @@ -448,8 +451,8 @@ void if_get_flags(struct interface *ifp) struct if_data ifd = {.ifi_link_state = 0}; struct if_data *ifdata = &ifd; - ifreq.ifr_data = (caddr_t)ifdata; - ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq, ifp->vrf->vrf_id); + ifreqdata.ifr_data = (caddr_t)ifdata; + ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreqdata, ifp->vrf->vrf_id); #endif if (ret == -1) @@ -459,12 +462,12 @@ void if_get_flags(struct interface *ifp) safe_strerror(errno)); else { if (ifdata->ifi_link_state >= LINK_STATE_UP) - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING); else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN) /* BSD traditionally treats UNKNOWN as UP */ - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING); else - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING); } #elif defined(HAVE_BSD_LINK_DETECT) @@ -489,14 +492,14 @@ void if_get_flags(struct interface *ifp) ifp->name, safe_strerror(errno)); } else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */ if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */ - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING); else - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING); } #endif /* HAVE_BSD_LINK_DETECT */ out: - if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff)); + if_flags_update(ifp, (ifreqflags.ifr_flags & 0x0000ffff)); } /* Set interface flags */ -- 2.39.5