mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	kconfig/menu.c: fix multiple references to expressions in menu_add_prop()
menu_add_prop() applies upper menus' visibilities to actual prompts
by AND-ing the prompts visibilities with the upper menus ones.
This creates a further reference to the menu's visibilities and when
the expression reduction functions do their work, they may remove or
modify expressions that have multiple references, thus causing
unpredictable side-effects.
The following example Kconfig constructs a case where this causes
problems: a menu and a prompt which's visibilities depend on the same
symbol.  When invoking mconf with this Kconfig and pressing "Z" we
see a problem caused by a free'd expression still referenced by the
menu's visibility:
------------------------------------------------------------------------
mainmenu "Kconfig Testing Configuration"
config VISIBLE
	def_bool n
config Placeholder
	bool "Place holder"
menu "Invisible"
	visible if VISIBLE
config TEST_VAR
	bool "Test option" if VISIBLE
endmenu
------------------------------------------------------------------------
This patch fixes this problem by creating copies of the menu's
visibility expressions before AND-ing them with the prompt's one.
Signed-off-by: Dirk Gouders <dirk@gouders.net>
[yann.morin.1998@free.fr: move variable into its block-scope,
                          keep lines <80 chars, typo]
Tested-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Reviewed-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
			
			
This commit is contained in:
		
							parent
							
								
									063f4661fd
								
							
						
					
					
						commit
						e983b7b17a
					
				
					 1 changed files with 14 additions and 1 deletions
				
			
		|  | @ -146,11 +146,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e | |||
| 			struct menu *menu = current_entry; | ||||
| 
 | ||||
| 			while ((menu = menu->parent) != NULL) { | ||||
| 				struct expr *dup_expr; | ||||
| 
 | ||||
| 				if (!menu->visibility) | ||||
| 					continue; | ||||
| 				/*
 | ||||
| 				 * Do not add a reference to the | ||||
| 				 * menu's visibility expression but | ||||
| 				 * use a copy of it.  Otherwise the | ||||
| 				 * expression reduction functions | ||||
| 				 * will modify expressions that have | ||||
| 				 * multiple references which can | ||||
| 				 * cause unwanted side effects. | ||||
| 				 */ | ||||
| 				dup_expr = expr_copy(menu->visibility); | ||||
| 
 | ||||
| 				prop->visible.expr | ||||
| 					= expr_alloc_and(prop->visible.expr, | ||||
| 							 menu->visibility); | ||||
| 							 dup_expr); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Dirk Gouders
						Dirk Gouders