Skip to content

Commit 043a283

Browse files
TaeheeYoogregkh
authored andcommitted
gtp: fix an use-after-free in ipv4_pdp_find()
[ Upstream commit 94dc550 ] ipv4_pdp_find() is called in TX packet path of GTP. ipv4_pdp_find() internally uses gtp->tid_hash to lookup pdp context. In the current code, gtp->tid_hash and gtp->addr_hash are freed by ->dellink(), which is gtp_dellink(). But gtp_dellink() would be called while packets are processing. So, gtp_dellink() should not free gtp->tid_hash and gtp->addr_hash. Instead, dev->priv_destructor() would be used because this callback is called after all packet processing safely. Test commands: ip link add veth1 type veth peer name veth2 ip a a 172.0.0.1/24 dev veth1 ip link set veth1 up ip a a 172.99.0.1/32 dev lo gtp-link add gtp1 & gtp-tunnel add gtp1 v1 200 100 172.99.0.2 172.0.0.2 ip r a 172.99.0.2/32 dev gtp1 ip link set gtp1 mtu 1500 ip netns add ns2 ip link set veth2 netns ns2 ip netns exec ns2 ip a a 172.0.0.2/24 dev veth2 ip netns exec ns2 ip link set veth2 up ip netns exec ns2 ip a a 172.99.0.2/32 dev lo ip netns exec ns2 ip link set lo up ip netns exec ns2 gtp-link add gtp2 & ip netns exec ns2 gtp-tunnel add gtp2 v1 100 200 172.99.0.1 172.0.0.1 ip netns exec ns2 ip r a 172.99.0.1/32 dev gtp2 ip netns exec ns2 ip link set gtp2 mtu 1500 hping3 172.99.0.2 -2 --flood & ip link del gtp1 Splat looks like: [ 72.568081][ T1195] BUG: KASAN: use-after-free in ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.568916][ T1195] Read of size 8 at addr ffff8880b9a35d28 by task hping3/1195 [ 72.569631][ T1195] [ 72.569861][ T1195] CPU: 2 PID: 1195 Comm: hping3 Not tainted 5.5.0-rc1 #199 [ 72.570547][ T1195] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 72.571438][ T1195] Call Trace: [ 72.571764][ T1195] dump_stack+0x96/0xdb [ 72.572171][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.572761][ T1195] print_address_description.constprop.5+0x1be/0x360 [ 72.573400][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.573971][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.574544][ T1195] __kasan_report+0x12a/0x16f [ 72.575014][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.575593][ T1195] kasan_report+0xe/0x20 [ 72.576004][ T1195] ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.576577][ T1195] gtp_build_skb_ip4+0x199/0x1420 [gtp] [ ... ] [ 72.647671][ T1195] BUG: unable to handle page fault for address: ffff8880b9a35d28 [ 72.648512][ T1195] #PF: supervisor read access in kernel mode [ 72.649158][ T1195] #PF: error_code(0x0000) - not-present page [ 72.649849][ T1195] PGD a6c01067 P4D a6c01067 PUD 11fb07067 PMD 11f939067 PTE 800fffff465ca060 [ 72.652958][ T1195] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 72.653834][ T1195] CPU: 2 PID: 1195 Comm: hping3 Tainted: G B 5.5.0-rc1 #199 [ 72.668062][ T1195] RIP: 0010:ipv4_pdp_find.isra.12+0x86/0x170 [gtp] [ ... ] [ 72.679168][ T1195] Call Trace: [ 72.679603][ T1195] gtp_build_skb_ip4+0x199/0x1420 [gtp] [ 72.681915][ T1195] ? ipv4_pdp_find.isra.12+0x170/0x170 [gtp] [ 72.682513][ T1195] ? lock_acquire+0x164/0x3b0 [ 72.682966][ T1195] ? gtp_dev_xmit+0x35e/0x890 [gtp] [ 72.683481][ T1195] gtp_dev_xmit+0x3c2/0x890 [gtp] [ ... ] Fixes: 459aa66 ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 83e00ef commit 043a283

File tree

1 file changed

+17
-17
lines changed

1 file changed

+17
-17
lines changed

drivers/net/gtp.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,16 @@ static void gtp_link_setup(struct net_device *dev)
644644
}
645645

646646
static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize);
647-
static void gtp_hashtable_free(struct gtp_dev *gtp);
648647
static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
649648

649+
static void gtp_destructor(struct net_device *dev)
650+
{
651+
struct gtp_dev *gtp = netdev_priv(dev);
652+
653+
kfree(gtp->addr_hash);
654+
kfree(gtp->tid_hash);
655+
}
656+
650657
static int gtp_newlink(struct net *src_net, struct net_device *dev,
651658
struct nlattr *tb[], struct nlattr *data[],
652659
struct netlink_ext_ack *extack)
@@ -681,13 +688,15 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
681688

682689
gn = net_generic(dev_net(dev), gtp_net_id);
683690
list_add_rcu(&gtp->list, &gn->gtp_dev_list);
691+
dev->priv_destructor = gtp_destructor;
684692

685693
netdev_dbg(dev, "registered new GTP interface\n");
686694

687695
return 0;
688696

689697
out_hashtable:
690-
gtp_hashtable_free(gtp);
698+
kfree(gtp->addr_hash);
699+
kfree(gtp->tid_hash);
691700
out_encap:
692701
gtp_encap_disable(gtp);
693702
return err;
@@ -696,9 +705,14 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
696705
static void gtp_dellink(struct net_device *dev, struct list_head *head)
697706
{
698707
struct gtp_dev *gtp = netdev_priv(dev);
708+
struct pdp_ctx *pctx;
709+
int i;
710+
711+
for (i = 0; i < gtp->hash_size; i++)
712+
hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
713+
pdp_context_delete(pctx);
699714

700715
gtp_encap_disable(gtp);
701-
gtp_hashtable_free(gtp);
702716
list_del_rcu(&gtp->list);
703717
unregister_netdevice_queue(dev, head);
704718
}
@@ -776,20 +790,6 @@ static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize)
776790
return -ENOMEM;
777791
}
778792

779-
static void gtp_hashtable_free(struct gtp_dev *gtp)
780-
{
781-
struct pdp_ctx *pctx;
782-
int i;
783-
784-
for (i = 0; i < gtp->hash_size; i++)
785-
hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
786-
pdp_context_delete(pctx);
787-
788-
synchronize_rcu();
789-
kfree(gtp->addr_hash);
790-
kfree(gtp->tid_hash);
791-
}
792-
793793
static struct sock *gtp_encap_enable_socket(int fd, int type,
794794
struct gtp_dev *gtp)
795795
{

0 commit comments

Comments
 (0)