Skip to content

Commit 1788b85

Browse files
TaeheeYoodavem330
authored andcommitted
gtp: fix use-after-free in gtp_encap_destroy()
gtp_encap_destroy() is called twice. 1. When interface is deleted. 2. When udp socket is destroyed. either gtp->sk0 or gtp->sk1u could be freed by sock_put() in gtp_encap_destroy(). so, when gtp_encap_destroy() is called again, it would uses freed sk pointer. patch makes gtp_encap_destroy() to set either gtp->sk0 or gtp->sk1u to null. in addition, both gtp->sk0 and gtp->sk1u pointer are protected by rtnl_lock. so, rtnl_lock() is added. Test command: gtp-link add gtp1 & killall gtp-link ip link del gtp1 Splat looks like: [ 83.182767] BUG: KASAN: use-after-free in __lock_acquire+0x3a20/0x46a0 [ 83.184128] Read of size 8 at addr ffff8880cc7d5360 by task ip/1008 [ 83.185567] CPU: 1 PID: 1008 Comm: ip Not tainted 5.2.0-rc6+ raspberrypi#50 [ 83.188469] Call Trace: [ ... ] [ 83.200126] lock_acquire+0x141/0x380 [ 83.200575] ? lock_sock_nested+0x3a/0xf0 [ 83.201069] _raw_spin_lock_bh+0x38/0x70 [ 83.201551] ? lock_sock_nested+0x3a/0xf0 [ 83.202044] lock_sock_nested+0x3a/0xf0 [ 83.202520] gtp_encap_destroy+0x18/0xe0 [gtp] [ 83.203065] gtp_encap_disable.isra.14+0x13/0x50 [gtp] [ 83.203687] gtp_dellink+0x56/0x170 [gtp] [ 83.204190] rtnl_delete_link+0xb4/0x100 [ ... ] [ 83.236513] Allocated by task 976: [ 83.236925] save_stack+0x19/0x80 [ 83.237332] __kasan_kmalloc.constprop.3+0xa0/0xd0 [ 83.237894] kmem_cache_alloc+0xd8/0x280 [ 83.238360] sk_prot_alloc.isra.42+0x50/0x200 [ 83.238874] sk_alloc+0x32/0x940 [ 83.239264] inet_create+0x283/0xc20 [ 83.239684] __sock_create+0x2dd/0x540 [ 83.240136] __sys_socket+0xca/0x1a0 [ 83.240550] __x64_sys_socket+0x6f/0xb0 [ 83.240998] do_syscall_64+0x9c/0x450 [ 83.241466] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 83.242061] [ 83.242249] Freed by task 0: [ 83.242616] save_stack+0x19/0x80 [ 83.243013] __kasan_slab_free+0x111/0x150 [ 83.243498] kmem_cache_free+0x89/0x250 [ 83.244444] __sk_destruct+0x38f/0x5a0 [ 83.245366] rcu_core+0x7e9/0x1c20 [ 83.245766] __do_softirq+0x213/0x8fa Fixes: 1e3a3ab ("gtp: make GTP sockets in gtp_newlink optional") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e198987 commit 1788b85

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/net/gtp.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,26 +285,37 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
285285
return gtp_rx(pctx, skb, hdrlen, gtp->role);
286286
}
287287

288-
static void gtp_encap_destroy(struct sock *sk)
288+
static void __gtp_encap_destroy(struct sock *sk)
289289
{
290290
struct gtp_dev *gtp;
291291

292292
lock_sock(sk);
293293
gtp = sk->sk_user_data;
294294
if (gtp) {
295+
if (gtp->sk0 == sk)
296+
gtp->sk0 = NULL;
297+
else
298+
gtp->sk1u = NULL;
295299
udp_sk(sk)->encap_type = 0;
296300
rcu_assign_sk_user_data(sk, NULL);
297301
sock_put(sk);
298302
}
299303
release_sock(sk);
300304
}
301305

306+
static void gtp_encap_destroy(struct sock *sk)
307+
{
308+
rtnl_lock();
309+
__gtp_encap_destroy(sk);
310+
rtnl_unlock();
311+
}
312+
302313
static void gtp_encap_disable_sock(struct sock *sk)
303314
{
304315
if (!sk)
305316
return;
306317

307-
gtp_encap_destroy(sk);
318+
__gtp_encap_destroy(sk);
308319
}
309320

310321
static void gtp_encap_disable(struct gtp_dev *gtp)
@@ -1038,6 +1049,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
10381049
return -EINVAL;
10391050
}
10401051

1052+
rtnl_lock();
10411053
rcu_read_lock();
10421054

10431055
gtp = gtp_find_dev(sock_net(skb->sk), info->attrs);
@@ -1062,6 +1074,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
10621074

10631075
out_unlock:
10641076
rcu_read_unlock();
1077+
rtnl_unlock();
10651078
return err;
10661079
}
10671080

0 commit comments

Comments
 (0)