| From 21730c84088d5d26991658e6eccc87350129ed50 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 16 Jun 2021 13:13:54 +0200 |
| Subject: media: dvb_net: avoid speculation from net slot |
| |
| From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| |
| [ Upstream commit abc0226df64dc137b48b911c1fe4319aec5891bb ] |
| |
| The risk of especulation is actually almost-non-existing here, |
| as there are very few users of TCP/IP using the DVB stack, |
| as, this is mainly used with DVB-S/S2 cards, and only by people |
| that receives TCP/IP from satellite connections, which limits |
| a lot the number of users of such feature(*). |
| |
| (*) In thesis, DVB-C cards could also benefit from it, but I'm |
| yet to see a hardware that supports it. |
| |
| Yet, fixing it is trivial. |
| |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/media/dvb-core/dvb_net.c | 25 +++++++++++++++++++------ |
| 1 file changed, 19 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c |
| index 89620da983ba..dddebea644bb 100644 |
| --- a/drivers/media/dvb-core/dvb_net.c |
| +++ b/drivers/media/dvb-core/dvb_net.c |
| @@ -45,6 +45,7 @@ |
| #include <linux/module.h> |
| #include <linux/kernel.h> |
| #include <linux/netdevice.h> |
| +#include <linux/nospec.h> |
| #include <linux/etherdevice.h> |
| #include <linux/dvb/net.h> |
| #include <linux/uio.h> |
| @@ -1462,14 +1463,20 @@ static int dvb_net_do_ioctl(struct file *file, |
| struct net_device *netdev; |
| struct dvb_net_priv *priv_data; |
| struct dvb_net_if *dvbnetif = parg; |
| + int if_num = dvbnetif->if_num; |
| |
| - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || |
| - !dvbnet->state[dvbnetif->if_num]) { |
| + if (if_num >= DVB_NET_DEVICES_MAX) { |
| ret = -EINVAL; |
| goto ioctl_error; |
| } |
| + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); |
| |
| - netdev = dvbnet->device[dvbnetif->if_num]; |
| + if (!dvbnet->state[if_num]) { |
| + ret = -EINVAL; |
| + goto ioctl_error; |
| + } |
| + |
| + netdev = dvbnet->device[if_num]; |
| |
| priv_data = netdev_priv(netdev); |
| dvbnetif->pid=priv_data->pid; |
| @@ -1522,14 +1529,20 @@ static int dvb_net_do_ioctl(struct file *file, |
| struct net_device *netdev; |
| struct dvb_net_priv *priv_data; |
| struct __dvb_net_if_old *dvbnetif = parg; |
| + int if_num = dvbnetif->if_num; |
| + |
| + if (if_num >= DVB_NET_DEVICES_MAX) { |
| + ret = -EINVAL; |
| + goto ioctl_error; |
| + } |
| + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); |
| |
| - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || |
| - !dvbnet->state[dvbnetif->if_num]) { |
| + if (!dvbnet->state[if_num]) { |
| ret = -EINVAL; |
| goto ioctl_error; |
| } |
| |
| - netdev = dvbnet->device[dvbnetif->if_num]; |
| + netdev = dvbnet->device[if_num]; |
| |
| priv_data = netdev_priv(netdev); |
| dvbnetif->pid=priv_data->pid; |
| -- |
| 2.30.2 |
| |