misc/176764: [net] [if_bridge] use-after-free in if_bridge

Adrian Chadd adrian at FreeBSD.org
Fri Mar 8 19:40:04 UTC 2013


>Number:         176764
>Category:       misc
>Synopsis:       [net] [if_bridge] use-after-free in if_bridge
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Mar 08 19:40:03 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Adrian Chadd
>Release:        
>Organization:
>Environment:
>Description:
Hi Adrian,

There seems to be a potential use-after-free in `sys/net/if_bridge.c'.
>From the following chunk of code:

#define GRAB_OUR_PACKETS(iface) \
        if ((iface)->if_type == IFT_GIF) \
                continue; \
        /* It is destined for us. */ \
        if (memcmp(IF_LLADDR((iface)), eh->ether_dhost,  ETHER_ADDR_LEN) == 0 \
            OR_CARP_CHECK_WE_ARE_DST((iface))                           \
            ) {                                                         \
                if ((iface)->if_type == IFT_BRIDGE) {                   \
                        ETHER_BPF_MTAP(iface, m);                       \
                        iface->if_ipackets++;                           \
                        /* Filter on the physical interface. */         \
                        if (pfil_local_phys &&                          \
                            (PFIL_HOOKED(&V_inet_pfil_hook)             \
                             OR_PFIL_HOOKED_INET6)) {                   \
                                if (bridge_pfil(&m, NULL, ifp,          \
                                    PFIL_IN) != 0 || m == NULL) {       \
                                        BRIDGE_UNLOCK(sc);              \
                                        return (NULL);                  \
                                }                                       \
                        }                                               \
                }                                                       \

bridge_pfil() might end-up changing the mbuf pointer (and the
underlying data), however, we still have a pending pointer to the data
through `eh' which is about to be dereferenced in the following call
to bridge_rtupdate():

                if (bif->bif_flags & IFBIF_LEARNING) {                  \
                        error = bridge_rtupdate(sc, eh->ether_shost,    \
                            vlan, bif, 0, IFBAF_DYNAMIC);               \

The obvious patch to fix this is attached to this mail.

>How-To-Repeat:
n/a
>Fix:
see attachment

Patch attached with submission follows:

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 85ad9fb..73ee550 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -2313,6 +2313,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
 					BRIDGE_UNLOCK(sc);		\
 					return (NULL);			\
 				}					\
+				eh = mtod(m, struct ether_header *);	\
 			}						\
 		}							\
 		if (bif->bif_flags & IFBIF_LEARNING) {			\


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list