aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 22:54:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-28 22:54:50 -0400
commit8f3603a210970d665e7cecf6623331ce6b24f713 (patch)
tree3dc33db5d8ea1c8a741a91d0e05c38629753352e
parentba14e961b4fc0b0efcb1b2af7aab605bfce55fb8 (diff)
parentede85e90be26e5de2a72f76feec01cfc5281d4bd (diff)
Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI fix from Ingo Molnar: "This fixes a bug in the efivars code" * 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: efi: Fix out-of-bounds read in variable_matches()
-rw-r--r--drivers/firmware/efi/vars.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 0ac594c0a234..34b741940494 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -202,29 +202,44 @@ static const struct variable_validate variable_validate[] = {
202 { NULL_GUID, "", NULL }, 202 { NULL_GUID, "", NULL },
203}; 203};
204 204
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 */
205static bool 216static bool
206variable_matches(const char *var_name, size_t len, const char *match_name, 217variable_matches(const char *var_name, size_t len, const char *match_name,
207 int *match) 218 int *match)
208{ 219{
209 for (*match = 0; ; (*match)++) { 220 for (*match = 0; ; (*match)++) {
210 char c = match_name[*match]; 221 char c = match_name[*match];
211 char u = var_name[*match];
212 222
213 /* Wildcard in the matching name means we've matched */ 223 switch (c) {
214 if (c == '*') 224 case '*':
225 /* Wildcard in @match_name means we've matched. */
215 return true; 226 return true;
216 227
217 /* Case sensitive match */ 228 case '\0':
218 if (!c && *match == len) 229 /* @match_name has ended. Has @var_name too? */
219 return true; 230 return (*match == len);
220 231
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;
222 return false; 240 return false;
223 241 }
224 if (!c)
225 return true;
226 } 242 }
227 return true;
228} 243}
229 244
230bool 245bool