kconfig: Add transitional symbol attribute for migration support

During kernel option migrations (e.g. CONFIG_CFI_CLANG to CONFIG_CFI),
existing .config files need to maintain backward compatibility while
preventing deprecated options from appearing in newly generated
configurations. This is challenging with existing Kconfig mechanisms
because:

1. Simply removing old options breaks existing .config files.
2. Manually listing an option as "deprecated" leaves it needlessly
   visible and still writes them to new .config files.
3. Using any method to remove visibility (.e.g no 'prompt', 'if n',
   etc) prevents the option from being processed at all.

Add a "transitional" attribute that creates symbols which are:
- Processed during configuration (can influence other symbols' defaults)
- Hidden from user menus (no prompts appear)
- Omitted from newly written .config files (gets migrated)
- Restricted to only having help sections (no defaults, selects, etc)
  making it truly just a "prior value pass-through" option.

The transitional syntax requires a type argument and prevents type
redefinition:

    config NEW_OPTION
        bool "New option"
        default OLD_OPTION

    config OLD_OPTION
        bool
        transitional
        help
          Transitional config for OLD_OPTION migration.

This allows seamless migration: olddefconfig processes existing
CONFIG_OLD_OPTION=y settings to enable CONFIG_NEW_OPTION=y, while
CONFIG_OLD_OPTION is omitted from newly generated .config files.

Added positive and negative testing via "testconfig" make target.

Co-developed-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/r/20250923213422.1105654-2-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
This commit is contained in:
Kees Cook
2025-09-23 14:34:18 -07:00
parent 64f4ea200e
commit f9afce4f32
12 changed files with 306 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
# SPDX-License-Identifier: GPL-2.0
# Test transitional symbols for config migration with all Kconfig types
# Enable module support for tristate testing
config MODULES
bool "Enable loadable module support"
modules
default y
# Basic migration tests for all types
config NEW_BOOL
bool "New bool option"
default OLD_BOOL
config OLD_BOOL
bool
transitional
config NEW_TRISTATE
tristate "New tristate option"
default OLD_TRISTATE
config OLD_TRISTATE
tristate
transitional
config NEW_STRING
string "New string option"
default OLD_STRING
config OLD_STRING
string
transitional
config NEW_HEX
hex "New hex option"
default OLD_HEX
config OLD_HEX
hex
transitional
config NEW_INT
int "New int option"
default OLD_INT
config OLD_INT
int
transitional
# Precedence tests for all types
config NEW_BOOL_PRECEDENCE
bool "New bool option with precedence"
default OLD_BOOL_PRECEDENCE
config OLD_BOOL_PRECEDENCE
bool
transitional
config NEW_STRING_PRECEDENCE
string "New string option with precedence"
default OLD_STRING_PRECEDENCE
config OLD_STRING_PRECEDENCE
string
transitional
config NEW_TRISTATE_PRECEDENCE
tristate "New tristate option with precedence"
default OLD_TRISTATE_PRECEDENCE
config OLD_TRISTATE_PRECEDENCE
tristate
transitional
config NEW_HEX_PRECEDENCE
hex "New hex option with precedence"
default OLD_HEX_PRECEDENCE
config OLD_HEX_PRECEDENCE
hex
transitional
config NEW_INT_PRECEDENCE
int "New int option with precedence"
default OLD_INT_PRECEDENCE
config OLD_INT_PRECEDENCE
int
transitional
# Test that help sections are allowed for transitional symbols
config OLD_WITH_HELP
bool
transitional
help
This transitional symbol has a help section to validate that help is allowed.
config REGULAR_OPTION
bool "Regular option"

View File

@@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-2.0
"""
Test transitional symbol migration functionality for all Kconfig types.
This tests that:
- OLD_* options in existing .config cause NEW_* options to be set
- OLD_* options are not written to the new .config file
- NEW_* options appear in the new .config file with correct values
- All Kconfig types work correctly: bool, tristate, string, hex, int
- User-set NEW values take precedence over conflicting OLD transitional values
"""
def test(conf):
# Run olddefconfig to process the migration with the initial config
assert conf.olddefconfig(dot_config='initial_config') == 0
# Check that the configuration matches expected output
assert conf.config_contains('expected_config')

View File

@@ -0,0 +1,12 @@
CONFIG_MODULES=y
CONFIG_NEW_BOOL=y
CONFIG_NEW_TRISTATE=m
CONFIG_NEW_STRING="test string"
CONFIG_NEW_HEX=0x1234
CONFIG_NEW_INT=42
# CONFIG_NEW_BOOL_PRECEDENCE is not set
CONFIG_NEW_STRING_PRECEDENCE="user value"
CONFIG_NEW_TRISTATE_PRECEDENCE=y
CONFIG_NEW_HEX_PRECEDENCE=0xABCD
CONFIG_NEW_INT_PRECEDENCE=100
# CONFIG_REGULAR_OPTION is not set

View File

@@ -0,0 +1,16 @@
CONFIG_MODULES=y
CONFIG_OLD_BOOL=y
CONFIG_OLD_TRISTATE=m
CONFIG_OLD_STRING="test string"
CONFIG_OLD_HEX=0x1234
CONFIG_OLD_INT=42
# CONFIG_NEW_BOOL_PRECEDENCE is not set
CONFIG_OLD_BOOL_PRECEDENCE=y
CONFIG_NEW_STRING_PRECEDENCE="user value"
CONFIG_OLD_STRING_PRECEDENCE="old value"
CONFIG_NEW_TRISTATE_PRECEDENCE=y
CONFIG_OLD_TRISTATE_PRECEDENCE=m
CONFIG_NEW_HEX_PRECEDENCE=0xABCD
CONFIG_OLD_HEX_PRECEDENCE=0x5678
CONFIG_NEW_INT_PRECEDENCE=100
CONFIG_OLD_INT_PRECEDENCE=200