diff options
author | Jeetesh Burman <jburman@nvidia.com> | 2018-02-14 16:18:40 +0530 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2018-04-03 10:44:20 -0700 |
commit | 92779c767e5e7c750cdea0c392e3f31befc37921 (patch) | |
tree | 405985c1aafde5cfa563fdf8aa3a214fa3adfc4a | |
parent | aba332e1dc32edfed73448364f2a88457738a270 (diff) |
drivers: speculative load before bound-check
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
Signed-off-by: Jeetesh Burman <jburman@nvidia.com>
(cherry picked from commit 5cabd53985a30aa818896abdb64564a74c09ab9c)
Reviewed-on: https://git-master.nvidia.com/r/1660772
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
-rw-r--r-- | drivers/media/i2c/ad9389b.c | 4 | ||||
-rw-r--r-- | drivers/media/i2c/adv7604.c | 4 | ||||
-rw-r--r-- | drivers/media/i2c/ov7670.c | 4 | ||||
-rw-r--r-- | drivers/media/i2c/ov9650.c | 3 | ||||
-rw-r--r-- | drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 | ||||
-rw-r--r-- | drivers/media/i2c/s5k6aa.c | 3 | ||||
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 3 |
7 files changed, 28 insertions, 0 deletions
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index 58344b6c3a55..436b9fd4775e 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -36,6 +36,7 @@ #include <media/v4l2-common.h> #include <media/v4l2-ctrls.h> #include <media/ad9389b.h> +#include <asm/barrier.h> static int debug; module_param(debug, int, 0644); @@ -627,6 +628,9 @@ static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi } 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], diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 31a63c9324fe..84202010d7d8 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -40,6 +40,7 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-chip-ident.h> #include <media/adv7604.h> +#include <asm/barrier.h> static int debug; module_param(debug, int, 0644); @@ -1593,6 +1594,9 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi return -EINVAL; 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; if (!edid->edid) diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 617ad3fff4aa..7124145a210b 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -21,6 +21,7 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-mediabus.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"); @@ -1087,6 +1088,9 @@ static int ov7670_enum_frameintervals(struct v4l2_subdev *sd, { if (interval->index >= ARRAY_SIZE(ov7670_frame_rates)) return -EINVAL; + + speculation_barrier(); + interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; interval->discrete.numerator = 1; interval->discrete.denominator = ov7670_frame_rates[interval->index]; diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 1dbb8118a285..47902efae8d4 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -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; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 9eac5310942f..a7078441e1e1 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -33,6 +33,7 @@ #include <media/v4l2-subdev.h> #include <media/v4l2-mediabus.h> #include <media/s5c73m3.h> +#include <asm/barrier.h> #include "s5c73m3.h" @@ -959,6 +960,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) @@ -1228,6 +1231,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; @@ -1272,6 +1277,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; diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index bdf5e3db31d1..aff91c3bcfde 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -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, diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index e3bdc3be91e1..60ba606afc56 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -23,6 +23,7 @@ #include <media/v4l2-fh.h> #include <media/v4l2-event.h> #include <media/videobuf2-core.h> +#include <asm/barrier.h> static int debug; module_param(debug, int, 0644); @@ -1800,6 +1801,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) return -EINVAL; } + speculation_barrier(); + vb = q->bufs[eb->index]; if (eb->plane >= vb->num_planes) { |