summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhengchao Shao <shaozhengchao@huawei.com>2022-10-28 10:56:50 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2022-11-07 13:43:02 +0100
commit8aa59e355949442c408408c2d836e561794c40a1 (patch)
tree5e406670e8df7b7a030e95aaf5fecba27ad04d00
parentcan: af_can: can_exit(): add missing dev_remove_pack() of canxl_packet (diff)
downloadlinux-8aa59e355949442c408408c2d836e561794c40a1.tar.xz
linux-8aa59e355949442c408408c2d836e561794c40a1.zip
can: af_can: fix NULL pointer dereference in can_rx_register()
It causes NULL pointer dereference when testing as following: (a) use syscall(__NR_socket, 0x10ul, 3ul, 0) to create netlink socket. (b) use syscall(__NR_sendmsg, ...) to create bond link device and vxcan link device, and bind vxcan device to bond device (can also use ifenslave command to bind vxcan device to bond device). (c) use syscall(__NR_socket, 0x1dul, 3ul, 1) to create CAN socket. (d) use syscall(__NR_bind, ...) to bind the bond device to CAN socket. The bond device invokes the can-raw protocol registration interface to receive CAN packets. However, ml_priv is not allocated to the dev, dev_rcv_lists is assigned to NULL in can_rx_register(). In this case, it will occur the NULL pointer dereference issue. The following is the stack information: BUG: kernel NULL pointer dereference, address: 0000000000000008 PGD 122a4067 P4D 122a4067 PUD 1223c067 PMD 0 Oops: 0000 [#1] PREEMPT SMP RIP: 0010:can_rx_register+0x12d/0x1e0 Call Trace: <TASK> raw_enable_filters+0x8d/0x120 raw_enable_allfilters+0x3b/0x130 raw_bind+0x118/0x4f0 __sys_bind+0x163/0x1a0 __x64_sys_bind+0x1e/0x30 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd </TASK> Fixes: 4e096a18867a ("net: introduce CAN specific pointer in the struct net_device") Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> Reviewed-by: Marc Kleine-Budde <mkl@pengutronix.de> Link: https://lore.kernel.org/all/20221028085650.170470-1-shaozhengchao@huawei.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--net/can/af_can.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 5e9e3e1e9825..27dcdcc0b808 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -450,7 +450,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
/* insert new receiver (dev,canid,mask) -> (func,data) */
- if (dev && dev->type != ARPHRD_CAN)
+ if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev)))
return -ENODEV;
if (dev && !net_eq(net, dev_net(dev)))