Skip to content
This repository was archived by the owner on Oct 3, 2024. It is now read-only.

Commit ac8d986

Browse files
committed
Merge branch 'mptcp-fixes'
Jeremy Kerr says: ==================== net: mctp: struct sock lifetime fixes This series is a set of fixes for the sock lifetime handling in the AF_MCTP code, fixing a uaf reported by Noam Rathaus <[email protected]>. The Fixes: tags indicate the original patches affected, but some tweaking to backport to those commits may be needed; I have a separate branch with backports to 5.15 if that helps with stable trees. Of course, any comments/queries most welcome. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents a9e9b78 + b98e1a0 commit ac8d986

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

net/mctp/af_mctp.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -544,9 +544,6 @@ static int mctp_sk_init(struct sock *sk)
544544

545545
static void mctp_sk_close(struct sock *sk, long timeout)
546546
{
547-
struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk);
548-
549-
del_timer_sync(&msk->key_expiry);
550547
sk_common_release(sk);
551548
}
552549

@@ -580,7 +577,14 @@ static void mctp_sk_unhash(struct sock *sk)
580577
spin_lock_irqsave(&key->lock, fl2);
581578
__mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_CLOSED);
582579
}
580+
sock_set_flag(sk, SOCK_DEAD);
583581
spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
582+
583+
/* Since there are no more tag allocations (we have removed all of the
584+
* keys), stop any pending expiry events. the timer cannot be re-queued
585+
* as the sk is no longer observable
586+
*/
587+
del_timer_sync(&msk->key_expiry);
584588
}
585589

586590
static struct proto mctp_proto = {

net/mctp/route.c

+21-13
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ static struct mctp_sk_key *mctp_key_alloc(struct mctp_sock *msk,
147147
key->valid = true;
148148
spin_lock_init(&key->lock);
149149
refcount_set(&key->refs, 1);
150+
sock_hold(key->sk);
150151

151152
return key;
152153
}
@@ -165,6 +166,7 @@ void mctp_key_unref(struct mctp_sk_key *key)
165166
mctp_dev_release_key(key->dev, key);
166167
spin_unlock_irqrestore(&key->lock, flags);
167168

169+
sock_put(key->sk);
168170
kfree(key);
169171
}
170172

@@ -177,6 +179,11 @@ static int mctp_key_add(struct mctp_sk_key *key, struct mctp_sock *msk)
177179

178180
spin_lock_irqsave(&net->mctp.keys_lock, flags);
179181

182+
if (sock_flag(&msk->sk, SOCK_DEAD)) {
183+
rc = -EINVAL;
184+
goto out_unlock;
185+
}
186+
180187
hlist_for_each_entry(tmp, &net->mctp.keys, hlist) {
181188
if (mctp_key_match(tmp, key->local_addr, key->peer_addr,
182189
key->tag)) {
@@ -198,6 +205,7 @@ static int mctp_key_add(struct mctp_sk_key *key, struct mctp_sock *msk)
198205
hlist_add_head(&key->sklist, &msk->keys);
199206
}
200207

208+
out_unlock:
201209
spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
202210

203211
return rc;
@@ -315,8 +323,8 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
315323

316324
static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
317325
{
326+
struct mctp_sk_key *key, *any_key = NULL;
318327
struct net *net = dev_net(skb->dev);
319-
struct mctp_sk_key *key;
320328
struct mctp_sock *msk;
321329
struct mctp_hdr *mh;
322330
unsigned long f;
@@ -361,13 +369,11 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
361369
* key for reassembly - we'll create a more specific
362370
* one for future packets if required (ie, !EOM).
363371
*/
364-
key = mctp_lookup_key(net, skb, MCTP_ADDR_ANY, &f);
365-
if (key) {
366-
msk = container_of(key->sk,
372+
any_key = mctp_lookup_key(net, skb, MCTP_ADDR_ANY, &f);
373+
if (any_key) {
374+
msk = container_of(any_key->sk,
367375
struct mctp_sock, sk);
368-
spin_unlock_irqrestore(&key->lock, f);
369-
mctp_key_unref(key);
370-
key = NULL;
376+
spin_unlock_irqrestore(&any_key->lock, f);
371377
}
372378
}
373379

@@ -419,14 +425,14 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
419425
* this function.
420426
*/
421427
rc = mctp_key_add(key, msk);
422-
if (rc) {
423-
kfree(key);
424-
} else {
428+
if (!rc)
425429
trace_mctp_key_acquire(key);
426430

427-
/* we don't need to release key->lock on exit */
428-
mctp_key_unref(key);
429-
}
431+
/* we don't need to release key->lock on exit, so
432+
* clean up here and suppress the unlock via
433+
* setting to NULL
434+
*/
435+
mctp_key_unref(key);
430436
key = NULL;
431437

432438
} else {
@@ -473,6 +479,8 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
473479
spin_unlock_irqrestore(&key->lock, f);
474480
mctp_key_unref(key);
475481
}
482+
if (any_key)
483+
mctp_key_unref(any_key);
476484
out:
477485
if (rc)
478486
kfree_skb(skb);

0 commit comments

Comments
 (0)