summaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/zconf.y
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2017-10-08 13:11:18 -0400
committerMasahiro Yamada <yamada.masahiro@socionext.com>2018-01-10 09:29:51 -0500
commit26e47a3c11a25cb3124facd3aae2737be6c568e4 (patch)
tree08638970d91f63777d703039c73bcd54acfc55c8 /scripts/kconfig/zconf.y
parent29c833061c1d8c2d1d23a62e7061561eadd76cdb (diff)
kconfig: Don't leak symbol names during parsing
Prior to this fix, zconf.y did not free symbol names from zconf.l in these contexts: - After T_CONFIG ('config LEAKED') - After T_MENUCONFIG ('menuconfig LEAKED') - After T_SELECT ('select LEAKED') - After T_IMPLY ('imply LEAKED') - After T_DEFAULT in a choice ('default LEAKED') All of these come in the form of T_WORD tokens, which always have their associated string allocated on the heap in zconf.l and need to be freed. Fix by introducing a new nonterminal 'nonconst_symbol' which takes a T_WORD, fetches the symbol, and then frees the T_WORD string. The already existing 'symbol' nonterminal works the same way but also accepts T_WORD_QUOTE, corresponding to a constant symbol. T_WORD_QUOTE should not be accepted in any of the contexts above, so the 'symbol' nonterminal can't be reused here. Fetching the symbol in 'nonconst_symbol' also removes a bunch of sym_lookup() calls from actions. Summary from Valgrind on 'menuconfig' (ARCH=x86) before the fix: LEAK SUMMARY: definitely lost: 711,571 bytes in 37,756 blocks ... Summary after the fix: LEAK SUMMARY: definitely lost: 387,504 bytes in 15,545 blocks ... Signed-off-by: Ulf Magnusson <ulfalizer@gmail.com> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'scripts/kconfig/zconf.y')
-rw-r--r--scripts/kconfig/zconf.y36
1 files changed, 19 insertions, 17 deletions
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 4b2cf4167415..616405b43e63 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -85,6 +85,7 @@ static struct menu *current_menu, *current_entry;
85%nonassoc T_NOT 85%nonassoc T_NOT
86 86
87%type <string> prompt 87%type <string> prompt
88%type <symbol> nonconst_symbol
88%type <symbol> symbol 89%type <symbol> symbol
89%type <expr> expr 90%type <expr> expr
90%type <expr> if_expr 91%type <expr> if_expr
@@ -145,12 +146,11 @@ option_error:
145 146
146/* config/menuconfig entry */ 147/* config/menuconfig entry */
147 148
148config_entry_start: T_CONFIG T_WORD T_EOL 149config_entry_start: T_CONFIG nonconst_symbol T_EOL
149{ 150{
150 struct symbol *sym = sym_lookup($2, 0); 151 $2->flags |= SYMBOL_OPTIONAL;
151 sym->flags |= SYMBOL_OPTIONAL; 152 menu_add_entry($2);
152 menu_add_entry(sym); 153 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
153 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
154}; 154};
155 155
156config_stmt: config_entry_start config_option_list 156config_stmt: config_entry_start config_option_list
@@ -159,12 +159,11 @@ config_stmt: config_entry_start config_option_list
159 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 159 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
160}; 160};
161 161
162menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL 162menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
163{ 163{
164 struct symbol *sym = sym_lookup($2, 0); 164 $2->flags |= SYMBOL_OPTIONAL;
165 sym->flags |= SYMBOL_OPTIONAL; 165 menu_add_entry($2);
166 menu_add_entry(sym); 166 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
167 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
168}; 167};
169 168
170menuconfig_stmt: menuconfig_entry_start config_option_list 169menuconfig_stmt: menuconfig_entry_start config_option_list
@@ -211,15 +210,15 @@ config_option: T_DEFAULT expr if_expr T_EOL
211 $1->stype); 210 $1->stype);
212}; 211};
213 212
214config_option: T_SELECT T_WORD if_expr T_EOL 213config_option: T_SELECT nonconst_symbol if_expr T_EOL
215{ 214{
216 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); 215 menu_add_symbol(P_SELECT, $2, $3);
217 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); 216 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
218}; 217};
219 218
220config_option: T_IMPLY T_WORD if_expr T_EOL 219config_option: T_IMPLY nonconst_symbol if_expr T_EOL
221{ 220{
222 menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3); 221 menu_add_symbol(P_IMPLY, $2, $3);
223 printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); 222 printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
224}; 223};
225 224
@@ -308,10 +307,10 @@ choice_option: T_OPTIONAL T_EOL
308 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); 307 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
309}; 308};
310 309
311choice_option: T_DEFAULT T_WORD if_expr T_EOL 310choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
312{ 311{
313 if ($1->stype == S_UNKNOWN) { 312 if ($1->stype == S_UNKNOWN) {
314 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); 313 menu_add_symbol(P_DEFAULT, $2, $3);
315 printd(DEBUG_PARSE, "%s:%d:default\n", 314 printd(DEBUG_PARSE, "%s:%d:default\n",
316 zconf_curname(), zconf_lineno()); 315 zconf_curname(), zconf_lineno());
317 } else 316 } else
@@ -491,7 +490,10 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
491 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } 490 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
492; 491;
493 492
494symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } 493/* For symbol definitions, selects, etc., where quotes are not accepted */
494nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
495
496symbol: nonconst_symbol
495 | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } 497 | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
496; 498;
497 499