Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/displayid: add displayid_get_header() and check bounds better

Add a helper to get a pointer to struct displayid_header. To be
pedantic, add buffer overflow checks to not touch the base if that
itself would overflow.

Cc: Iaroslav Boliukin <iam@lach.pw>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/4a03b3a5132642d3cdb6d4c2641422955a917292.1676580180.git.jani.nikula@intel.com

authored by

Jani Nikula and committed by
Dmitry Osipenko
5bacecc3 25c0e406

+16 -1
+16 -1
drivers/gpu/drm/drm_displayid.c
··· 7 7 #include <drm/drm_edid.h> 8 8 #include <drm/drm_print.h> 9 9 10 + static const struct displayid_header * 11 + displayid_get_header(const u8 *displayid, int length, int index) 12 + { 13 + const struct displayid_header *base; 14 + 15 + if (sizeof(*base) > length - index) 16 + return ERR_PTR(-EINVAL); 17 + 18 + base = (const struct displayid_header *)&displayid[index]; 19 + 20 + return base; 21 + } 22 + 10 23 static int validate_displayid(const u8 *displayid, int length, int idx) 11 24 { 12 25 int i, dispid_length; 13 26 u8 csum = 0; 14 27 const struct displayid_header *base; 15 28 16 - base = (const struct displayid_header *)&displayid[idx]; 29 + base = displayid_get_header(displayid, length, idx); 30 + if (IS_ERR(base)) 31 + return PTR_ERR(base); 17 32 18 33 DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", 19 34 base->rev, base->bytes, base->prod_id, base->ext_count);