4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Laszlo Ersek <ler...@redhat.com>

commit 630ba0cc7a6dbafbdee43795617c872b35cde1b4 upstream.

The variable_matches() function can currently read "var_name[len]", for
example when:

 - var_name[0] == 'a',
 - len == 1
 - match_name points to the NUL-terminated string "ab".

This function is supposed to accept "var_name" inputs that are not
NUL-terminated (hence the "len" parameter"). Document the function, and
access "var_name[*match]" only if "*match" is smaller than "len".

Reported-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
Cc: Peter Jones <pjo...@redhat.com>
Cc: Matthew Garrett <mj...@coreos.com>
Cc: Jason Andryuk <jandr...@gmail.com>
Cc: Jani Nikula <jani.nik...@linux.intel.com>
Link: http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/86906
Signed-off-by: Matt Fleming <m...@codeblueprint.co.uk>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/firmware/efi/vars.c |   39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -202,29 +202,44 @@ static const struct variable_validate va
        { NULL_GUID, "", NULL },
 };
 
+/*
+ * Check if @var_name matches the pattern given in @match_name.
+ *
+ * @var_name: an array of @len non-NUL characters.
+ * @match_name: a NUL-terminated pattern string, optionally ending in "*". A
+ *              final "*" character matches any trailing characters @var_name,
+ *              including the case when there are none left in @var_name.
+ * @match: on output, the number of non-wildcard characters in @match_name
+ *         that @var_name matches, regardless of the return value.
+ * @return: whether @var_name fully matches @match_name.
+ */
 static bool
 variable_matches(const char *var_name, size_t len, const char *match_name,
                 int *match)
 {
        for (*match = 0; ; (*match)++) {
                char c = match_name[*match];
-               char u = var_name[*match];
 
-               /* Wildcard in the matching name means we've matched */
-               if (c == '*')
+               switch (c) {
+               case '*':
+                       /* Wildcard in @match_name means we've matched. */
                        return true;
 
-               /* Case sensitive match */
-               if (!c && *match == len)
-                       return true;
-
-               if (c != u)
+               case '\0':
+                       /* @match_name has ended. Has @var_name too? */
+                       return (*match == len);
+
+               default:
+                       /*
+                        * We've reached a non-wildcard char in @match_name.
+                        * Continue only if there's an identical character in
+                        * @var_name.
+                        */
+                       if (*match < len && c == var_name[*match])
+                               continue;
                        return false;
-
-               if (!c)
-                       return true;
+               }
        }
-       return true;
 }
 
 bool


Reply via email to