mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
62b7f5931c
bcm2708: boot tested on RPi B+ v1.2
bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G
bcm2710: boot tested on RPi 3B v1.2
bcm2711: boot tested on RPi 4B v1.1 4G
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
(cherry-picked from commit f07e572f64
)
142 lines
4.2 KiB
Diff
142 lines
4.2 KiB
Diff
From fade8b3cf37785297b4f8a9bbd13ab107208af5a Mon Sep 17 00:00:00 2001
|
|
From: Hans de Goede <hdegoede@redhat.com>
|
|
Date: Mon, 18 Nov 2019 16:51:22 +0100
|
|
Subject: [PATCH] drm/modes: parse_cmdline: Fix possible reference past
|
|
end of string
|
|
|
|
Commit 8582e244e5fe72d2e9ace186fa8f3ed3bb4122e1 upstream.
|
|
|
|
Before this commit, if the last option of a video=... option is for
|
|
example "rotate" without a "=<value>" after it then delim will point to
|
|
the terminating 0 of the string, and value which is sets to <delim + 1>
|
|
will point one position past the end of the string.
|
|
|
|
This commit fixes this by enforcing that the contents of delim equals '='
|
|
as it should be for options which take a value, this check is done in a
|
|
new drm_mode_parse_cmdline_int helper function which factors out the
|
|
common integer parsing code for all the options which take an int.
|
|
|
|
Acked-by: Maxime Ripard <mripard@kernel.org>
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
Link: https://patchwork.freedesktop.org/patch/msgid/20191118155134.30468-1-hdegoede@redhat.com
|
|
---
|
|
drivers/gpu/drm/drm_modes.c | 68 ++++++++++++++++---------------------
|
|
1 file changed, 30 insertions(+), 38 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/drm_modes.c
|
|
+++ b/drivers/gpu/drm/drm_modes.c
|
|
@@ -1568,11 +1568,34 @@ static int drm_mode_parse_cmdline_res_mo
|
|
return 0;
|
|
}
|
|
|
|
+static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret)
|
|
+{
|
|
+ const char *value;
|
|
+ char *endp;
|
|
+
|
|
+ /*
|
|
+ * delim must point to the '=', otherwise it is a syntax error and
|
|
+ * if delim points to the terminating zero, then delim + 1 wil point
|
|
+ * past the end of the string.
|
|
+ */
|
|
+ if (*delim != '=')
|
|
+ return -EINVAL;
|
|
+
|
|
+ value = delim + 1;
|
|
+ *int_ret = simple_strtol(value, &endp, 10);
|
|
+
|
|
+ /* Make sure we have parsed something */
|
|
+ if (endp == value)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int drm_mode_parse_cmdline_options(char *str, size_t len,
|
|
const struct drm_connector *connector,
|
|
struct drm_cmdline_mode *mode)
|
|
{
|
|
- unsigned int rotation = 0;
|
|
+ unsigned int deg, margin, rotation = 0;
|
|
char *sep = str;
|
|
|
|
while ((sep = strchr(sep, ','))) {
|
|
@@ -1588,13 +1611,7 @@ static int drm_mode_parse_cmdline_option
|
|
}
|
|
|
|
if (!strncmp(option, "rotate", delim - option)) {
|
|
- const char *value = delim + 1;
|
|
- unsigned int deg;
|
|
-
|
|
- deg = simple_strtol(value, &sep, 10);
|
|
-
|
|
- /* Make sure we have parsed something */
|
|
- if (sep == value)
|
|
+ if (drm_mode_parse_cmdline_int(delim, °))
|
|
return -EINVAL;
|
|
|
|
switch (deg) {
|
|
@@ -1619,57 +1636,32 @@ static int drm_mode_parse_cmdline_option
|
|
}
|
|
} else if (!strncmp(option, "reflect_x", delim - option)) {
|
|
rotation |= DRM_MODE_REFLECT_X;
|
|
- sep = delim;
|
|
} else if (!strncmp(option, "reflect_y", delim - option)) {
|
|
rotation |= DRM_MODE_REFLECT_Y;
|
|
- sep = delim;
|
|
} else if (!strncmp(option, "margin_right", delim - option)) {
|
|
- const char *value = delim + 1;
|
|
- unsigned int margin;
|
|
-
|
|
- margin = simple_strtol(value, &sep, 10);
|
|
-
|
|
- /* Make sure we have parsed something */
|
|
- if (sep == value)
|
|
+ if (drm_mode_parse_cmdline_int(delim, &margin))
|
|
return -EINVAL;
|
|
|
|
mode->tv_margins.right = margin;
|
|
} else if (!strncmp(option, "margin_left", delim - option)) {
|
|
- const char *value = delim + 1;
|
|
- unsigned int margin;
|
|
-
|
|
- margin = simple_strtol(value, &sep, 10);
|
|
-
|
|
- /* Make sure we have parsed something */
|
|
- if (sep == value)
|
|
+ if (drm_mode_parse_cmdline_int(delim, &margin))
|
|
return -EINVAL;
|
|
|
|
mode->tv_margins.left = margin;
|
|
} else if (!strncmp(option, "margin_top", delim - option)) {
|
|
- const char *value = delim + 1;
|
|
- unsigned int margin;
|
|
-
|
|
- margin = simple_strtol(value, &sep, 10);
|
|
-
|
|
- /* Make sure we have parsed something */
|
|
- if (sep == value)
|
|
+ if (drm_mode_parse_cmdline_int(delim, &margin))
|
|
return -EINVAL;
|
|
|
|
mode->tv_margins.top = margin;
|
|
} else if (!strncmp(option, "margin_bottom", delim - option)) {
|
|
- const char *value = delim + 1;
|
|
- unsigned int margin;
|
|
-
|
|
- margin = simple_strtol(value, &sep, 10);
|
|
-
|
|
- /* Make sure we have parsed something */
|
|
- if (sep == value)
|
|
+ if (drm_mode_parse_cmdline_int(delim, &margin))
|
|
return -EINVAL;
|
|
|
|
mode->tv_margins.bottom = margin;
|
|
} else {
|
|
return -EINVAL;
|
|
}
|
|
+ sep = delim;
|
|
}
|
|
|
|
if (!(rotation & DRM_MODE_ROTATE_MASK))
|