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