From: Simon Glass <simon.glass@canonical.com> The get_token() function allocates memory for t.val when parsing keywords and string literals, but callers do not free this memory. Fix this by: - Initialising t.val to NULL in get_token() so free() is safe for T_EOL/T_EOF tokens which do not allocate - Adding free(t.val) calls in parse_menu(), parse_label_menu(), parse_label(), and parse_pxefile_top() after token processing Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/pxe_parse.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/boot/pxe_parse.c b/boot/pxe_parse.c index 6d148756b0d..8c720db5e75 100644 --- a/boot/pxe_parse.c +++ b/boot/pxe_parse.c @@ -232,6 +232,7 @@ static void get_token(char **p, struct token *t, enum lex_state state) char *c = *p; t->type = T_INVALID; + t->val = NULL; /* eat non EOL whitespace */ while (isblank(*c)) @@ -418,6 +419,7 @@ static int parse_menu(struct pxe_context *ctx, char **c, struct pxe_menu *cfg, char *s = *c; int err = 0; + t.val = NULL; get_token(c, &t, L_KEYWORD); switch (t.type) { @@ -434,6 +436,7 @@ static int parse_menu(struct pxe_context *ctx, char **c, struct pxe_menu *cfg, printf("Ignoring malformed menu command: %.*s\n", (int)(*c - s), s); } + free(t.val); if (err < 0) return err; @@ -452,6 +455,7 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg, char *s; s = *c; + t.val = NULL; get_token(c, &t, L_KEYWORD); switch (t.type) { @@ -471,6 +475,7 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg, (int)(*c - s), s); } + free(t.val); eol_or_eof(c); return 0; @@ -534,8 +539,10 @@ static int parse_label(char **c, struct pxe_menu *cfg) } list_add_tail(&label->list, &cfg->labels); + t.val = NULL; while (1) { s = *c; + free(t.val); get_token(c, &t, L_KEYWORD); err = 0; @@ -595,8 +602,10 @@ static int parse_label(char **c, struct pxe_menu *cfg) if (p) { label->say = strndup(*c + 1, p - *c - 1); - if (!label->say) + if (!label->say) { + free(t.val); return -ENOMEM; + } *c = p; } break; @@ -608,11 +617,14 @@ static int parse_label(char **c, struct pxe_menu *cfg) * something for the menu level context to handle. */ *c = s; + free(t.val); return 1; } - if (err < 0) + if (err < 0) { + free(t.val); return err; + } } } @@ -637,8 +649,10 @@ int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base, return -EMLINK; } + t.val = NULL; while (1) { s = p; + free(t.val); get_token(&p, &t, L_KEYWORD); err = 0; @@ -686,6 +700,7 @@ int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base, case T_EOL: break; case T_EOF: + free(t.val); return 1; default: printf("Ignoring unknown command: %.*s\n", @@ -693,7 +708,9 @@ int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base, eol_or_eof(&p); } - if (err < 0) + if (err < 0) { + free(t.val); return err; + } } } -- 2.43.0