]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: dvb_net: avoid speculation from net slot
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Wed, 16 Jun 2021 11:13:54 +0000 (13:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Jul 2021 14:22:32 +0000 (16:22 +0200)
[ 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

index ce4332e80a910fe653632ad4a9b870eb675bd592..735baa74043c708ace9036663c075bbc342a9c08 100644 (file)
@@ -57,6 +57,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>
@@ -1350,14 +1351,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;
@@ -1410,14 +1417,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;