From a607d76b504f00322c02ddf655f90511cb7f81fd Mon Sep 17 00:00:00 2001 From: Kaustubh Pandey Date: Tue, 12 Jun 2018 10:09:53 +0530 Subject: [PATCH 1/4] net: core: null pointer derefernce in sockev_client_cb sockev_client_cb creates a netlink message and populates the nlmsg_data using the socket->sock information. If socket is closed, while the nlmsg_data is being populated, a null pointer dereference occurs. BUG: KASAN: null-ptr-deref in sockev_client_cb+0x1e4/0x310 Read of size 2 at addr 0000000000000010 by task syz-executor/9398 CPU: 6 PID: 9398 Comm: syz-executor Tainted: G W O 4.9.92+ #1 Call trace: [] sockev_client_cb+0x1e4/0x310 [] notifier_call_chain+0x94/0xe0 [] __blocking_notifier_call_chain+0x6c/0xb8 [] blocking_notifier_call_chain+0x40/0x50 [] sockev_notify net/socket.c:180 [inline] [] SYSC_listen net/socket.c:1446 [inline] [] SyS_listen+0x1e0/0x1f8 [] el0_svc_naked+0x24/0x28 CR's Fixed: 2251042 Change-Id: Iad9eb58cd05fcdc0b5cc1ed24de56b69abb532b4 Signed-off-by: Sharath Chandra Vurukala Signed-off-by: Tejaswi Tanikella Signed-off-by: Kaustubh Pandey Acked-by: Chinmay Agarwal --- net/core/sockev_nlmcast.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c index 749ffb81c87c..b9a47d4a650e 100644 --- a/net/core/sockev_nlmcast.c +++ b/net/core/sockev_nlmcast.c @@ -68,14 +68,17 @@ static int sockev_client_cb(struct notifier_block *nb, struct nlmsghdr *nlh; struct sknlsockevmsg *smsg; struct socket *sock; + struct sock *sk; sock = (struct socket *)data; - if (socknlmsgsk == 0) - goto done; - if ((socknlmsgsk == NULL) || (sock == NULL) || (sock->sk == NULL)) + if (!socknlmsgsk || !sock) goto done; - if (sock->sk->sk_family != AF_INET && sock->sk->sk_family != AF_INET6) + sk = sock->sk; + if (!sk) + goto done; + + if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) goto done; if (event != SOCKEV_BIND && event != SOCKEV_LISTEN) @@ -96,12 +99,11 @@ static int sockev_client_cb(struct notifier_block *nb, smsg = nlmsg_data(nlh); smsg->pid = current->pid; _sockev_event(event, smsg->event, sizeof(smsg->event)); - smsg->skfamily = sock->sk->sk_family; - smsg->skstate = sock->sk->sk_state; - smsg->skprotocol = sock->sk->sk_protocol; - smsg->sktype = sock->sk->sk_type; - smsg->skflags = sock->sk->sk_flags; - + smsg->skfamily = sk->sk_family; + smsg->skstate = sk->sk_state; + smsg->skprotocol = sk->sk_protocol; + smsg->sktype = sk->sk_type; + smsg->skflags = sk->sk_flags; nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL); done: return 0; From a84417e849b0b2a01caba7e919bad0912108d853 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Wed, 24 Apr 2019 11:35:26 +0530 Subject: [PATCH 2/4] net: sockev: avoid races between sockev and socket_close Use-after-free is seen when sending a sockev netlink message since socket is not held which can race with sk_free. KASAN: use-after-free in sockev_client_cb+0x41c/0x4b8 in net/core/sockev_nlmcast.c:104 Read of size 2 at addr ffffffc08420c550 Call trace: dump_backtrace+0x0/0x388 arch/arm64/kernel/time.c:55 show_stack+0x24/0x30 arch/arm64/kernel/traps.c:152 __dump_stack+0x24/0x2c lib/dump_stack.c:17 dump_stack+0x8c/0xd0 lib/dump_stack.c:53 print_address_description+0x74/0x234 mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report+0x240/0x264 mm/kasan/report.c:412 __asan_report_load2_noabort+0x2c/0x38 mm/kasan/report.c:431 sockev_client_cb+0x41c/0x4b8 net/core/sockev_nlmcast.c:104 notifier_call_chain+0x104/0x158 kernel/notifier.c:93 __blocking_notifier_call_chain+0x80/0xb0 kernel/notifier.c:317 blocking_notifier_call_chain+0x3c/0x4c kernel/notifier.c:328 sockev_notify+0x30/0x3c net/socket.c:181 SYSC_bind net/socket.c:1509 [inline] SyS_bind+0x1ec/0x30c net/socket.c:1489 el0_svc_naked+0x34/0x38 Freed by task 19460: save_stack mm/kasan/kasan.c:447 [inline] set_track mm/kasan/kasan.c:459 [inline] __kasan_slab_free+0x134/0x20c mm/kasan/kasan.c:520 kasan_slab_free+0x10/0x1c mm/kasan/kasan.c:527 slab_free_hook mm/slub.c:1401 [inline] slab_free_freelist_hook mm/slub.c:1422 [inline] slab_free mm/slub.c:2979 [inline] kmem_cache_free+0x114/0x664 mm/slub.c:3001 sk_prot_free net/core/sock.c:1504 [inline] __sk_destruct+0x324/0x3c0 net/core/sock.c:1585 __sk_free+0x180/0x200 net/core/sock.c:1601 sk_free+0x44/0x50 net/core/sock.c:1612 sock_put include/net/sock.h:1643 [inline] sk_common_release+0x198/0x20c net/core/sock.c:3014 raw_close+0x38/0x44 net/ipv4/raw.c:703 inet_release+0x128/0x15c net/ipv4/af_inet.c:446 __sock_release+0xb8/0x258 net/socket.c:614 sock_close+0x24/0x34 net/socket.c:1150 __fput+0x1f4/0x4e4 fs/file_table.c:345 ____fput+0x20/0x2c fs/file_table.c:380 task_work_run+0x9c/0x174 kernel/task_work.c:113 Change-Id: Idb4335889b6e4228f36d76ca5b6156cc5e5838da Signed-off-by: Sharath Chandra Vurukala --- net/core/sockev_nlmcast.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c index b9a47d4a650e..adf15daa816b 100644 --- a/net/core/sockev_nlmcast.c +++ b/net/core/sockev_nlmcast.c @@ -72,11 +72,13 @@ static int sockev_client_cb(struct notifier_block *nb, sock = (struct socket *)data; if (!socknlmsgsk || !sock) - goto done; + goto sk_null; sk = sock->sk; if (!sk) - goto done; + goto sk_null; + + sock_hold(sk); if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) goto done; @@ -106,6 +108,8 @@ static int sockev_client_cb(struct notifier_block *nb, smsg->skflags = sk->sk_flags; nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL); done: + sock_put(sk); +sk_null: return 0; } From 23bb563ae6958a6933605973158d1074198a9c2a Mon Sep 17 00:00:00 2001 From: Puranam V G Tejaswi Date: Thu, 6 Aug 2020 23:35:06 +0530 Subject: [PATCH 3/4] msm: kgsl: Correctly clean up dma buffer attachment in case of error In kgsl_ioctl_gpuobj_import(), user memory of type KGSL_USER_MEM_TYPE_ADDR can also lead to setting up a dma buffer. When attaching mem entry to process fails, dma buffer attachment is cleaned up only in case of KGSL_USER_MEM_TYPE_DMABUF. Similar situation can arise in case of kgsl_ioctl_map_user_mem(). Fix this by obtaining user memory type from the memdesc flags. Change-Id: I502bd0ae19241802e8f835f20391b2ce67999418 Signed-off-by: Puranam V G Tejaswi --- drivers/gpu/msm/kgsl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index aa6a30b77013..bfec37c2cddc 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2433,7 +2433,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv, return 0; unmap: - if (param->type == KGSL_USER_MEM_TYPE_DMABUF) { + if (kgsl_memdesc_usermem_type(&entry->memdesc) == KGSL_MEM_ENTRY_ION) { kgsl_destroy_ion(entry->priv_data); entry->memdesc.sgt = NULL; } @@ -2708,7 +2708,7 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, return result; error_attach: - switch (memtype) { + switch (kgsl_memdesc_usermem_type(&entry->memdesc)) { case KGSL_MEM_ENTRY_ION: kgsl_destroy_ion(entry->priv_data); entry->memdesc.sgt = NULL; From 75b4770b3a0cc931efb3699c37f2c47869ce3338 Mon Sep 17 00:00:00 2001 From: Indira Biruduraju Date: Tue, 11 Aug 2020 15:24:16 +0530 Subject: [PATCH 4/4] msm: kgsl: Remove VM_MAYWRITE flag to restrict mprotect When VM_MAYWRITE flag is used during mmap(), mprotect() can be used later to change the protection of memstore to allow write. Make sure this does not happen by removing VM_MAYWRITE from the vm_flags of vma. Change-Id: I6f69f05858ea40611d512cfa796caabeaa88cdb5 Signed-off-by: Indira Biruduraju --- drivers/gpu/msm/kgsl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index bfec37c2cddc..1b99f74801d5 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -3357,6 +3357,8 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma) if (vma->vm_flags & VM_WRITE) return -EPERM; + vma->vm_flags &= ~VM_MAYWRITE; + if (memdesc->size != vma_size) { KGSL_MEM_ERR(device, "memstore bad size: %d should be %llu\n", vma_size, memdesc->size);