1 From fade8b3cf37785297b4f8a9bbd13ab107208af5a Mon Sep 17 00:00:00 2001
2 From: Hans de Goede <hdegoede@redhat.com>
3 Date: Mon, 18 Nov 2019 16:51:22 +0100
4 Subject: [PATCH] drm/modes: parse_cmdline: Fix possible reference past
7 Commit 8582e244e5fe72d2e9ace186fa8f3ed3bb4122e1 upstream.
9 Before this commit, if the last option of a video=... option is for
10 example "rotate" without a "=<value>" after it then delim will point to
11 the terminating 0 of the string, and value which is sets to <delim + 1>
12 will point one position past the end of the string.
14 This commit fixes this by enforcing that the contents of delim equals '='
15 as it should be for options which take a value, this check is done in a
16 new drm_mode_parse_cmdline_int helper function which factors out the
17 common integer parsing code for all the options which take an int.
19 Acked-by: Maxime Ripard <mripard@kernel.org>
20 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
21 Link: https://patchwork.freedesktop.org/patch/msgid/20191118155134.30468-1-hdegoede@redhat.com
23 drivers/gpu/drm/drm_modes.c | 68 ++++++++++++++++---------------------
24 1 file changed, 30 insertions(+), 38 deletions(-)
26 --- a/drivers/gpu/drm/drm_modes.c
27 +++ b/drivers/gpu/drm/drm_modes.c
28 @@ -1568,11 +1568,34 @@ static int drm_mode_parse_cmdline_res_mo
32 +static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret)
38 + * delim must point to the '=', otherwise it is a syntax error and
39 + * if delim points to the terminating zero, then delim + 1 wil point
40 + * past the end of the string.
46 + *int_ret = simple_strtol(value, &endp, 10);
48 + /* Make sure we have parsed something */
55 static int drm_mode_parse_cmdline_options(char *str, size_t len,
56 const struct drm_connector *connector,
57 struct drm_cmdline_mode *mode)
59 - unsigned int rotation = 0;
60 + unsigned int deg, margin, rotation = 0;
63 while ((sep = strchr(sep, ','))) {
64 @@ -1588,13 +1611,7 @@ static int drm_mode_parse_cmdline_option
67 if (!strncmp(option, "rotate", delim - option)) {
68 - const char *value = delim + 1;
71 - deg = simple_strtol(value, &sep, 10);
73 - /* Make sure we have parsed something */
75 + if (drm_mode_parse_cmdline_int(delim, °))
79 @@ -1619,57 +1636,32 @@ static int drm_mode_parse_cmdline_option
81 } else if (!strncmp(option, "reflect_x", delim - option)) {
82 rotation |= DRM_MODE_REFLECT_X;
84 } else if (!strncmp(option, "reflect_y", delim - option)) {
85 rotation |= DRM_MODE_REFLECT_Y;
87 } else if (!strncmp(option, "margin_right", delim - option)) {
88 - const char *value = delim + 1;
89 - unsigned int margin;
91 - margin = simple_strtol(value, &sep, 10);
93 - /* Make sure we have parsed something */
95 + if (drm_mode_parse_cmdline_int(delim, &margin))
98 mode->tv_margins.right = margin;
99 } else if (!strncmp(option, "margin_left", delim - option)) {
100 - const char *value = delim + 1;
101 - unsigned int margin;
103 - margin = simple_strtol(value, &sep, 10);
105 - /* Make sure we have parsed something */
107 + if (drm_mode_parse_cmdline_int(delim, &margin))
110 mode->tv_margins.left = margin;
111 } else if (!strncmp(option, "margin_top", delim - option)) {
112 - const char *value = delim + 1;
113 - unsigned int margin;
115 - margin = simple_strtol(value, &sep, 10);
117 - /* Make sure we have parsed something */
119 + if (drm_mode_parse_cmdline_int(delim, &margin))
122 mode->tv_margins.top = margin;
123 } else if (!strncmp(option, "margin_bottom", delim - option)) {
124 - const char *value = delim + 1;
125 - unsigned int margin;
127 - margin = simple_strtol(value, &sep, 10);
129 - /* Make sure we have parsed something */
131 + if (drm_mode_parse_cmdline_int(delim, &margin))
134 mode->tv_margins.bottom = margin;
141 if (!(rotation & DRM_MODE_ROTATE_MASK))