1From c6c426e5ab6ea715153b72584de6bd8c82f698ec Mon Sep 17 00:00:00 2001 2From: Chris Coulson <chris.coulson@canonical.com> 3Date: Wed, 18 Nov 2020 00:59:24 +0000 4Subject: [PATCH] kern/parser: Fix a memory leak 5 6The getline() function supplied to grub_parser_split_cmdline() returns 7a newly allocated buffer and can be called multiple times, but the 8returned buffer is never freed. 9 10Signed-off-by: Chris Coulson <chris.coulson@canonical.com> 11Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 12Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 13--- 14 grub-core/kern/parser.c | 20 ++++++++++++++++---- 15 1 file changed, 16 insertions(+), 4 deletions(-) 16 17diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c 18index d1cf061..39e4df6 100644 19--- a/grub-core/kern/parser.c 20+++ b/grub-core/kern/parser.c 21@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *cmdline, 22 char buffer[1024]; 23 char *bp = buffer; 24 char *rd = (char *) cmdline; 25+ char *rp = rd; 26 char varname[200]; 27 char *vp = varname; 28 char *args; 29@@ -149,10 +150,18 @@ grub_parser_split_cmdline (const char *cmdline, 30 *argv = NULL; 31 do 32 { 33- if (!rd || !*rd) 34+ if (rp == NULL || *rp == '\0') 35 { 36+ if (rd != cmdline) 37+ { 38+ grub_free (rd); 39+ rd = rp = NULL; 40+ } 41 if (getline) 42- getline (&rd, 1, getline_data); 43+ { 44+ getline (&rd, 1, getline_data); 45+ rp = rd; 46+ } 47 else 48 break; 49 } 50@@ -160,12 +169,12 @@ grub_parser_split_cmdline (const char *cmdline, 51 if (!rd) 52 break; 53 54- for (; *rd; rd++) 55+ for (; *rp != '\0'; rp++) 56 { 57 grub_parser_state_t newstate; 58 char use; 59 60- newstate = grub_parser_cmdline_state (state, *rd, &use); 61+ newstate = grub_parser_cmdline_state (state, *rp, &use); 62 63 /* If a variable was being processed and this character does 64 not describe the variable anymore, write the variable to 65@@ -198,6 +207,9 @@ grub_parser_split_cmdline (const char *cmdline, 66 } 67 while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); 68 69+ if (rd != cmdline) 70+ grub_free (rd); 71+ 72 /* A special case for when the last character was part of a 73 variable. */ 74 add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); 75-- 762.14.2 77 78