Skip to content

Commit 513f5c3

Browse files
Laszlo Ersekgregkh
authored andcommitted
efi: Fix out-of-bounds read in variable_matches()
commit 630ba0c 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 <chris@chris-wilson.co.uk> Signed-off-by: Laszlo Ersek <lersek@redhat.com> Cc: Peter Jones <pjones@redhat.com> Cc: Matthew Garrett <mjg59@coreos.com> Cc: Jason Andryuk <jandryuk@gmail.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Link: http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/86906 Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c92003c commit 513f5c3

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

drivers/firmware/efi/vars.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,29 +202,44 @@ static const struct variable_validate variable_validate[] = {
202202
{ NULL_GUID, "", NULL },
203203
};
204204

205+
/*
206+
* Check if @var_name matches the pattern given in @match_name.
207+
*
208+
* @var_name: an array of @len non-NUL characters.
209+
* @match_name: a NUL-terminated pattern string, optionally ending in "*". A
210+
* final "*" character matches any trailing characters @var_name,
211+
* including the case when there are none left in @var_name.
212+
* @match: on output, the number of non-wildcard characters in @match_name
213+
* that @var_name matches, regardless of the return value.
214+
* @return: whether @var_name fully matches @match_name.
215+
*/
205216
static bool
206217
variable_matches(const char *var_name, size_t len, const char *match_name,
207218
int *match)
208219
{
209220
for (*match = 0; ; (*match)++) {
210221
char c = match_name[*match];
211-
char u = var_name[*match];
212222

213-
/* Wildcard in the matching name means we've matched */
214-
if (c == '*')
223+
switch (c) {
224+
case '*':
225+
/* Wildcard in @match_name means we've matched. */
215226
return true;
216227

217-
/* Case sensitive match */
218-
if (!c && *match == len)
219-
return true;
228+
case '\0':
229+
/* @match_name has ended. Has @var_name too? */
230+
return (*match == len);
220231

221-
if (c != u)
232+
default:
233+
/*
234+
* We've reached a non-wildcard char in @match_name.
235+
* Continue only if there's an identical character in
236+
* @var_name.
237+
*/
238+
if (*match < len && c == var_name[*match])
239+
continue;
222240
return false;
223-
224-
if (!c)
225-
return true;
241+
}
226242
}
227-
return true;
228243
}
229244

230245
bool

0 commit comments

Comments
 (0)