xref: /OK3568_Linux_fs/buildroot/boot/grub2/0127-kern-parser-Fix-a-memory-leak.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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