diff options
author | Ulf Magnusson <ulfalizer@gmail.com> | 2017-10-08 13:11:18 -0400 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-01-10 09:29:51 -0500 |
commit | 26e47a3c11a25cb3124facd3aae2737be6c568e4 (patch) | |
tree | 08638970d91f63777d703039c73bcd54acfc55c8 /scripts/kconfig/zconf.y | |
parent | 29c833061c1d8c2d1d23a62e7061561eadd76cdb (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.y | 36 |
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 | ||
148 | config_entry_start: T_CONFIG T_WORD T_EOL | 149 | config_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 | ||
156 | config_stmt: config_entry_start config_option_list | 156 | config_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 | ||
162 | menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL | 162 | menuconfig_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 | ||
170 | menuconfig_stmt: menuconfig_entry_start config_option_list | 169 | menuconfig_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 | ||
214 | config_option: T_SELECT T_WORD if_expr T_EOL | 213 | config_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 | ||
220 | config_option: T_IMPLY T_WORD if_expr T_EOL | 219 | config_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 | ||
311 | choice_option: T_DEFAULT T_WORD if_expr T_EOL | 310 | choice_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 | ||
494 | symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } | 493 | /* For symbol definitions, selects, etc., where quotes are not accepted */ |
494 | nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; | ||
495 | |||
496 | symbol: 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 | ||