https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289017
Bug ID: 289017
Summary: [lagg] A time-of-check to time-of-use (TOCTOU) race
exists in the Link Aggregation (LAGG) network
subsystem
Product: Base System
Version: 14.3-RELEASE
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: kern
Assignee: [email protected]
Reporter: [email protected]
A time-of-check to time-of-use (TOCTOU) race exists in the net
subsystem at several call sites of lagg_proto_start(),
lagg_proto_input(), and lagg_proto_portreq().
In the SIOCSLAGG branch of lagg_ioctl(), updating sc is performed
by calling lagg_proto_detach() followed by lagg_proto_attach(). In
the middle of this sequence, sc->sc_proto is set to
LAGG_PROTO_NONE. This change is not mutually exclusive with
NET_EPOCH read-side critical sections, so sc->sc_proto may still
change while a reader is executing under NET_EPOCH.
For example, in lagg_transmit_ethernet(), the code checks:
if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0)
Because this check is protected only by NET_EPOCH, after it passes,
sc->sc_proto may still be changed to LAGG_PROTO_NONE. As a result,
lagg_proto_start(sc, m) will index
lagg_protos[sc->sc_proto].pr_start(sc, m) with
LAGG_PROTO_NONE. Since the LAGG_PROTO_NONE entry in lagg_protos
does not provide any function pointers, this leads to a NULL function
pointer dereference. The same issue exists at the call site in
lagg_transmit_infiniband().
Similarly, the call sites of lagg_proto_input() in
lagg_input_ethernet() and lagg_input_infiniband(), and the call
sites of lagg_proto_portreq() via lagg_port2req() in
lagg_port_ioctl() and lagg_ioctl(), are subject to the same race.
We also examined call sites of the related helpers
lagg_proto_addport(), lagg_proto_delport(), lagg_proto_linkstate(),
lagg_proto_init(), lagg_proto_stop(), lagg_proto_lladdr(), and
lagg_proto_request(). Their invocations are protected by the
appropriate locks, and we did not find a TOCTOU issue there.
Suggested fix: Before invoking the above helpers, snapshot
sc->sc_proto into a local variable, validate it, and use that single
value for both the check and the subsequent function-pointer call.
--
You are receiving this mail because:
You are the assignee for the bug.