]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
drivers: speculative load before bound-check
authorJames Huang <jamehuang@nvidia.com>
Fri, 2 Feb 2018 04:22:57 +0000 (12:22 +0800)
committerWinnie Hsu <whsu@nvidia.com>
Sat, 3 Feb 2018 02:52:13 +0000 (18:52 -0800)
Data can be speculatively loaded from memory and stay in cache even
when bound check fails. This can lead to unintended information
disclosure via side-channel analysis.

To mitigate this problem, insert speculation barrier.

Bug 1964290
CVE-2017-5753

Change-Id: I7382dbcc6e9f352fafd457301beafe753925f3c4
Signed-off-by: Hien Goi <hgoi@nvidia.com>
Signed-off-by: James Huang <jamehuang@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1650791
Reviewed-by: Hayden Du <haydend@nvidia.com>
(cherry picked from commit 5cabd53985a30aa818896abdb64564a74c09ab9c)
Reviewed-on: https://git-master.nvidia.com/r/1651418
Reviewed-by: Prabhu Kuttiyam <pkuttiyam@nvidia.com>
Tested-by: Prabhu Kuttiyam <pkuttiyam@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
drivers/media/i2c/ad9389b.c
drivers/media/i2c/adv7511.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/i2c/ov2659.c
drivers/media/i2c/ov7670.c
drivers/media/i2c/ov9650.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5k6aa.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-v4l2.c

index 69094ab047b1d955040f6f6e2a7afd10287fec6c..3e0445fd552177999537f172e5bddcd76e92648c 100644 (file)
@@ -36,6 +36,7 @@
 #include <media/v4l2-dv-timings.h>
 #include <media/v4l2-ctrls.h>
 #include <media/ad9389b.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -688,6 +689,9 @@ static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
        }
        if (edid->start_block >= state->edid.segments * 2)
                return -E2BIG;
+
+       speculation_barrier();
+
        if (edid->blocks + edid->start_block >= state->edid.segments * 2)
                edid->blocks = state->edid.segments * 2 - edid->start_block;
        memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
index c24839cfcc3565ca83de9f4e6aeba8a9d57d46a2..a10fb95a0c63b437750ff858c459fe1bd7332ef9 100644 (file)
@@ -33,6 +33,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/adv7511.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -908,6 +909,8 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 
        if (edid->start_block >= state->edid.segments * 2)
                return -EINVAL;
+       
+       speculation_barrier();
 
        if (edid->start_block + edid->blocks > state->edid.segments * 2)
                edid->blocks = state->edid.segments * 2 - edid->start_block;
index 01adcdc52346634cda4c7553bab709faf0df59fc..7eb46304d67a2c10b16c891ecdf5b52d92aef5a7 100644 (file)
@@ -45,6 +45,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/v4l2-of.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -2000,6 +2001,8 @@ static int adv76xx_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
        if (edid->start_block >= state->edid.blocks)
                return -EINVAL;
 
+       speculation_barrier();
+
        if (edid->start_block + edid->blocks > state->edid.blocks)
                edid->blocks = state->edid.blocks - edid->start_block;
 
index b7269b8f040d741f93fa218a6fbe1634cd7c5be9..cb37c114f5eb028d70b882d9c681f88a8c9712fc 100644 (file)
@@ -44,6 +44,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/adv7842.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -2270,6 +2271,8 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
        if (edid->start_block >= 2)
                return -EINVAL;
 
+       speculation_barrier();
+
        if (edid->start_block + edid->blocks > 2)
                edid->blocks = 2 - edid->start_block;
 
index 49109f4f5bb4a14ec471b4915606439a57f3495e..baa7e983c3547a23c1287c20cc96997f1987472f 100644 (file)
@@ -46,6 +46,7 @@
 #include <media/v4l2-mediabus.h>
 #include <media/v4l2-of.h>
 #include <media/v4l2-subdev.h>
+#include <asm/barrier.h>
 
 #define DRIVER_NAME "ov2659"
 
@@ -1022,6 +1023,8 @@ static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd,
        if (fse->index >= ARRAY_SIZE(ov2659_framesizes))
                return -EINVAL;
 
+       speculation_barrier();
+
        while (--i)
                if (fse->code == ov2659_formats[i].code)
                        break;
index e1b5dc84c14e86be96b998f847c0b7dfe1951975..0b0605ced3cf7605a2a9d2c918984c1472fe7d38 100644 (file)
@@ -21,6 +21,7 @@
 #include <media/v4l2-mediabus.h>
 #include <media/v4l2-image-sizes.h>
 #include <media/ov7670.h>
+#include <asm/barrier.h>
 
 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
 MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
@@ -1089,6 +1090,8 @@ static int ov7670_enum_frame_interval(struct v4l2_subdev *sd,
        if (fie->index >= ARRAY_SIZE(ov7670_frame_rates))
                return -EINVAL;
 
+       speculation_barrier();
+
        /*
         * Check if the width/height is valid.
         *
index 1ee6a5527c384676333587115a18565ba76f0519..7153edc4fcca504d66b7ef15f073af6492bfec5a 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
 #include <media/ov9650.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -1086,6 +1087,8 @@ static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd,
        if (fse->index >= ARRAY_SIZE(ov965x_framesizes))
                return -EINVAL;
 
+       speculation_barrier();
+
        while (--i)
                if (fse->code == ov965x_formats[i].code)
                        break;
index 51b26010403c1be42126ad481fd3b6b465cd2fbc..0774003744054038154f5538ae4b6e09e72ccee4 100644 (file)
@@ -38,6 +38,7 @@
 #include <media/v4l2-of.h>
 
 #include "s5c73m3.h"
+#include <asm/barrier.h>
 
 int s5c73m3_dbg;
 module_param_named(debug, s5c73m3_dbg, int, 0644);
@@ -965,6 +966,8 @@ static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd,
        if (fie->index >= ARRAY_SIZE(s5c73m3_intervals))
                return -EINVAL;
 
+       speculation_barrier();
+
        mutex_lock(&state->lock);
        fi = &s5c73m3_intervals[fie->index];
        if (fie->width > fi->size.width || fie->height > fi->size.height)
@@ -1239,6 +1242,8 @@ static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd,
        if (fse->index >= s5c73m3_resolutions_len[idx])
                return -EINVAL;
 
+       speculation_barrier();
+
        fse->min_width  = s5c73m3_resolutions[idx][fse->index].width;
        fse->max_width  = fse->min_width;
        fse->max_height = s5c73m3_resolutions[idx][fse->index].height;
@@ -1298,6 +1303,8 @@ static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd,
        if (fse->index >= s5c73m3_resolutions_len[idx])
                return -EINVAL;
 
+       speculation_barrier();
+
        fse->min_width  = s5c73m3_resolutions[idx][fse->index].width;
        fse->max_width  = fse->min_width;
        fse->max_height = s5c73m3_resolutions[idx][fse->index].height;
index d0ad6a25bdabf2e602bdf4b8dd9ab7db384a4f4a..0ec0e48da767489c6b66f09ae30e49736c8991fe 100644 (file)
@@ -29,6 +29,7 @@
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
 #include <media/s5k6aa.h>
+#include <asm/barrier.h>
 
 static int debug;
 module_param(debug, int, 0644);
@@ -1006,6 +1007,8 @@ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
        if (fie->index >= ARRAY_SIZE(s5k6aa_intervals))
                return -EINVAL;
 
+       speculation_barrier();
+
        v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
                              S5K6AA_WIN_WIDTH_MAX, 1,
                              &fie->height, S5K6AA_WIN_HEIGHT_MIN,
index 47f37683893a76ac71324b9ae1d77e4043613bcd..9b5c2cb16ebf0459308c2b4e2f709b9dd97faafc 100644 (file)
@@ -29,6 +29,7 @@
 #include <trace/events/vb2.h>
 
 #include "videobuf2-internal.h"
+#include <asm/barrier.h>
 
 int vb2_debug;
 EXPORT_SYMBOL_GPL(vb2_debug);
@@ -1879,6 +1880,8 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
                return -EINVAL;
        }
 
+       speculation_barrier();
+
        vb = q->bufs[index];
 
        if (plane >= vb->num_planes) {
index 502984c724ff5efd14ef10250dd5d8e653468111..461eba1270460bc12ae1cac7147b2bc258cf7289 100644 (file)
@@ -32,6 +32,7 @@
 #include <media/videobuf2-v4l2.h>
 
 #include "videobuf2-internal.h"
+#include <asm/barrier.h>
 
 /* Flags that are set by the vb2 core */
 #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
@@ -158,6 +159,8 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
                return -EINVAL;
        }
 
+       speculation_barrier();
+
        if (q->bufs[b->index] == NULL) {
                /* Should never happen */
                dprintk(1, "%s: buffer is NULL\n", opname);
@@ -464,6 +467,9 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
                dprintk(1, "buffer index out of range\n");
                return -EINVAL;
        }
+
+       speculation_barrier();
+
        vb = q->bufs[b->index];
        ret = __verify_planes_array(vb, b);