Message ID | 20231005094639.387019-2-mkl@pengutronix.de (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net,1/7] can: j1939: Fix UAF in j1939_sk_match_filter during setsockopt(SO_J1939_FILTER) | expand |
On Thu, 5 Oct 2023 11:46:33 +0200 Marc Kleine-Budde wrote: > Lock jsk->sk to prevent UAF when setsockopt(..., SO_J1939_FILTER, ...) > modifies jsk->filters while receiving packets. Doesn't it potentially introduce sleep in atomic? j1939_sk_recv_match() spin_lock_bh(&priv->j1939_socks_lock); j1939_sk_recv_match_one() j1939_sk_match_filter() lock_sock() sleep
Hi Jakub, On Thu, Oct 05, 2023 at 09:44:21AM -0700, Jakub Kicinski wrote: > On Thu, 5 Oct 2023 11:46:33 +0200 Marc Kleine-Budde wrote: > > Lock jsk->sk to prevent UAF when setsockopt(..., SO_J1939_FILTER, ...) > > modifies jsk->filters while receiving packets. > > Doesn't it potentially introduce sleep in atomic? > > j1939_sk_recv_match() > spin_lock_bh(&priv->j1939_socks_lock); > j1939_sk_recv_match_one() > j1939_sk_match_filter() > lock_sock() > sleep Good point! Thank you for the review. @Sili Luo, can you please take a look at this? Regards, Oleksij
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c index b28c976f52a0..2ce24bf78c72 100644 --- a/net/can/j1939/socket.c +++ b/net/can/j1939/socket.c @@ -262,12 +262,17 @@ static bool j1939_sk_match_dst(struct j1939_sock *jsk, static bool j1939_sk_match_filter(struct j1939_sock *jsk, const struct j1939_sk_buff_cb *skcb) { - const struct j1939_filter *f = jsk->filters; - int nfilter = jsk->nfilters; + const struct j1939_filter *f; + int nfilter; + + lock_sock(&jsk->sk); + + f = jsk->filters; + nfilter = jsk->nfilters; if (!nfilter) /* receive all when no filters are assigned */ - return true; + goto filter_match_found; for (; nfilter; ++f, --nfilter) { if ((skcb->addr.pgn & f->pgn_mask) != f->pgn) @@ -276,9 +281,15 @@ static bool j1939_sk_match_filter(struct j1939_sock *jsk, continue; if ((skcb->addr.src_name & f->name_mask) != f->name) continue; - return true; + goto filter_match_found; } + + release_sock(&jsk->sk); return false; + +filter_match_found: + release_sock(&jsk->sk); + return true; } static bool j1939_sk_recv_match_one(struct j1939_sock *jsk,