mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	kconfig: Don't leak main menus during parsing
If a 'mainmenu' entry appeared in the Kconfig files, two things would leak: - The 'struct property' allocated for the default "Linux Kernel Configuration" prompt. - The string for the T_WORD/T_WORD_QUOTE prompt after the T_MAINMENU token, allocated on the heap in zconf.l. To fix it, introduce a new 'no_mainmenu_stmt' nonterminal that matches if there's no 'mainmenu' and adds the default prompt. That means the prompt only gets allocated once regardless of whether there's a 'mainmenu' statement or not, and managing it becomes simple. Summary from Valgrind on 'menuconfig' (ARCH=x86) before the fix: LEAK SUMMARY: definitely lost: 344,568 bytes in 14,352 blocks ... Summary after the fix: LEAK SUMMARY: definitely lost: 344,440 bytes in 14,350 blocks ... Signed-off-by: Ulf Magnusson <ulfalizer@gmail.com> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
		
							parent
							
								
									bc28fe1d5e
								
							
						
					
					
						commit
						0724a7c32a
					
				
					 1 changed files with 24 additions and 9 deletions
				
			
		| 
						 | 
					@ -109,7 +109,27 @@ static struct menu *current_menu, *current_entry;
 | 
				
			||||||
%%
 | 
					%%
 | 
				
			||||||
input: nl start | start;
 | 
					input: nl start | start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start: mainmenu_stmt stmt_list | stmt_list;
 | 
					start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mainmenu entry */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mainmenu_stmt: T_MAINMENU prompt nl
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						menu_add_prompt(P_MENU, $2, NULL);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Default main menu, if there's no mainmenu entry */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no_mainmenu_stmt: /* empty */
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Hack: Keep the main menu title on the heap so we can safely free it
 | 
				
			||||||
 | 
						 * later regardless of whether it comes from the 'prompt' in
 | 
				
			||||||
 | 
						 * mainmenu_stmt or here
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						menu_add_prompt(P_MENU, strdup("Linux Kernel Configuration"), NULL);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stmt_list:
 | 
					stmt_list:
 | 
				
			||||||
	  /* empty */
 | 
						  /* empty */
 | 
				
			||||||
| 
						 | 
					@ -352,13 +372,6 @@ if_block:
 | 
				
			||||||
	| if_block choice_stmt
 | 
						| if_block choice_stmt
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* mainmenu entry */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mainmenu_stmt: T_MAINMENU prompt nl
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	menu_add_prompt(P_MENU, $2, NULL);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* menu entry */
 | 
					/* menu entry */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
menu: T_MENU prompt T_EOL
 | 
					menu: T_MENU prompt T_EOL
 | 
				
			||||||
| 
						 | 
					@ -507,6 +520,7 @@ word_opt: /* empty */			{ $$ = NULL; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void conf_parse(const char *name)
 | 
					void conf_parse(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						const char *tmp;
 | 
				
			||||||
	struct symbol *sym;
 | 
						struct symbol *sym;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -514,7 +528,6 @@ void conf_parse(const char *name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sym_init();
 | 
						sym_init();
 | 
				
			||||||
	_menu_init();
 | 
						_menu_init();
 | 
				
			||||||
	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (getenv("ZCONF_DEBUG"))
 | 
						if (getenv("ZCONF_DEBUG"))
 | 
				
			||||||
		zconfdebug = 1;
 | 
							zconfdebug = 1;
 | 
				
			||||||
| 
						 | 
					@ -524,8 +537,10 @@ void conf_parse(const char *name)
 | 
				
			||||||
	if (!modules_sym)
 | 
						if (!modules_sym)
 | 
				
			||||||
		modules_sym = sym_find( "n" );
 | 
							modules_sym = sym_find( "n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = rootmenu.prompt->text;
 | 
				
			||||||
	rootmenu.prompt->text = _(rootmenu.prompt->text);
 | 
						rootmenu.prompt->text = _(rootmenu.prompt->text);
 | 
				
			||||||
	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
 | 
						rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
 | 
				
			||||||
 | 
						free((char*)tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	menu_finalize(&rootmenu);
 | 
						menu_finalize(&rootmenu);
 | 
				
			||||||
	for_all_symbols(i, sym) {
 | 
						for_all_symbols(i, sym) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue