mirror of
https://github.com/torvalds/linux.git
synced 2025-11-01 00:58:39 +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;
|
struct menu *menu = current_entry;
|
||||||
|
|
||||||
while ((menu = menu->parent) != NULL) {
|
while ((menu = menu->parent) != NULL) {
|
||||||
|
struct expr *dup_expr;
|
||||||
|
|
||||||
if (!menu->visibility)
|
if (!menu->visibility)
|
||||||
continue;
|
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
|
prop->visible.expr
|
||||||
= expr_alloc_and(prop->visible.expr,
|
= expr_alloc_and(prop->visible.expr,
|
||||||
menu->visibility);
|
dup_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue