linux-stable/scripts/kconfig
Masahiro Yamada 6bfda3ef7f kconfig: fix comparison to constant symbols, 'm', 'n'
[ Upstream commit aabdc960a2 ]

Currently, comparisons to 'm' or 'n' result in incorrect output.

[Test Code]

    config MODULES
            def_bool y
            modules

    config A
            def_tristate m

    config B
            def_bool A > n

CONFIG_B is unset, while CONFIG_B=y is expected.

The reason for the issue is because Kconfig compares the tristate values
as strings.

Currently, the .type fields in the constant symbol definitions,
symbol_{yes,mod,no} are unspecified, i.e., S_UNKNOWN.

When expr_calc_value() evaluates 'A > n', it checks the types of 'A' and
'n' to determine how to compare them.

The left-hand side, 'A', is a tristate symbol with a value of 'm', which
corresponds to a numeric value of 1. (Internally, 'y', 'm', and 'n' are
represented as 2, 1, and 0, respectively.)

The right-hand side, 'n', has an unknown type, so it is treated as the
string "n" during the comparison.

expr_calc_value() compares two values numerically only when both can
have numeric values. Otherwise, they are compared as strings.

    symbol    numeric value    ASCII code
    -------------------------------------
      y           2             0x79
      m           1             0x6d
      n           0             0x6e

'm' is greater than 'n' if compared numerically (since 1 is greater
than 0), but smaller than 'n' if compared as strings (since the ASCII
code 0x6d is smaller than 0x6e).

Specifying .type=S_TRISTATE for symbol_{yes,mod,no} fixes the above
test code.

Doing so, however, would cause a regression to the following test code.

[Test Code 2]

    config MODULES
            def_bool n
            modules

    config A
            def_tristate n

    config B
            def_bool A = m

You would get CONFIG_B=y, while CONFIG_B should not be set.

The reason is because sym_get_string_value() turns 'm' into 'n' when the
module feature is disabled. Consequently, expr_calc_value() evaluates
'A = n' instead of 'A = m'. This oddity has been hidden because the type
of 'm' was previously S_UNKNOWN instead of S_TRISTATE.

sym_get_string_value() should not tweak the string because the tristate
value has already been correctly calculated. There is no reason to
return the string "n" where its tristate value is mod.

Fixes: 31847b67be ("kconfig: allow use of relations other than (in)equality")
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-06-16 13:23:37 +02:00
..
lxdialog
tests
.gitignore
Makefile
conf.c
confdata.c
expr.c
expr.h
gconf-cfg.sh
gconf.c
gconf.glade
images.c
kconf_id.c
list.h
lkc.h
lkc_proto.h
mconf-cfg.sh
mconf.c
menu.c
merge_config.sh
nconf-cfg.sh
nconf.c kconfig: nconf: stop endless search loops 2021-05-22 10:59:41 +02:00
nconf.gui.c
nconf.h
preprocess.c kconfig: fix possible buffer overflow 2023-09-23 10:48:12 +02:00
qconf-cfg.sh
qconf.cc kconfig: qconf: fix signal connection to invalid slots 2020-08-26 10:31:04 +02:00
qconf.h
streamline_config.pl
symbol.c kconfig: fix comparison to constant symbols, 'm', 'n' 2024-06-16 13:23:37 +02:00
util.c
zconf.l kconfig: fix infinite loop when expanding a macro at the end of file 2024-03-26 18:22:42 -04:00
zconf.y