Patch "kconfig: fix comparison to constant symbols, 'm', 'n'" has been added to the 6.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    kconfig: fix comparison to constant symbols, 'm', 'n'

to the 6.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     kconfig-fix-comparison-to-constant-symbols-m-n.patch
and it can be found in the queue-6.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit abfec13214d324dadf62942be8062c101450681c
Author: Masahiro Yamada <masahiroy@xxxxxxxxxx>
Date:   Sun May 19 18:22:27 2024 +0900

    kconfig: fix comparison to constant symbols, 'm', 'n'
    
    [ Upstream commit aabdc960a283ba78086b0bf66ee74326f49e218e ]
    
    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: 31847b67bec0 ("kconfig: allow use of relations other than (in)equality")
    Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 81fe1884ef8ae..67a509778135b 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -14,6 +14,7 @@
 
 struct symbol symbol_yes = {
 	.name = "y",
+	.type = S_TRISTATE,
 	.curr = { "y", yes },
 	.menus = LIST_HEAD_INIT(symbol_yes.menus),
 	.flags = SYMBOL_CONST|SYMBOL_VALID,
@@ -21,6 +22,7 @@ struct symbol symbol_yes = {
 
 struct symbol symbol_mod = {
 	.name = "m",
+	.type = S_TRISTATE,
 	.curr = { "m", mod },
 	.menus = LIST_HEAD_INIT(symbol_mod.menus),
 	.flags = SYMBOL_CONST|SYMBOL_VALID,
@@ -28,6 +30,7 @@ struct symbol symbol_mod = {
 
 struct symbol symbol_no = {
 	.name = "n",
+	.type = S_TRISTATE,
 	.curr = { "n", no },
 	.menus = LIST_HEAD_INIT(symbol_no.menus),
 	.flags = SYMBOL_CONST|SYMBOL_VALID,
@@ -788,8 +791,7 @@ const char *sym_get_string_value(struct symbol *sym)
 		case no:
 			return "n";
 		case mod:
-			sym_calc_value(modules_sym);
-			return (modules_sym->curr.tri == no) ? "n" : "m";
+			return "m";
 		case yes:
 			return "y";
 		}




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux