From 237d1b4483a4e6f7fcdc6f87e339280fcc1534ab Mon Sep 17 00:00:00 2001 From: maade93791 <70593890+maade69@users.noreply.github.com> Date: Fri, 1 May 2026 01:21:30 +0300 Subject: [PATCH 1/4] system_properties: add extended sysprop overrides the implementation is based on appcompat overrides, with several changes: * deny writes to a set of sysprops * inherit overrides from `ro.appcompat_override` --- libc/bionic/system_property_api.cpp | 5 +++ libc/include/sys/system_properties.h | 2 + libc/libc.map.txt | 1 + .../system_properties/system_properties.h | 2 + libc/system_properties/system_properties.cpp | 37 +++++++++++++++++++ 5 files changed, 47 insertions(+) diff --git a/libc/bionic/system_property_api.cpp b/libc/bionic/system_property_api.cpp index 34438e7afd1..580deeee31b 100644 --- a/libc/bionic/system_property_api.cpp +++ b/libc/bionic/system_property_api.cpp @@ -135,3 +135,8 @@ int __system_properties_zygote_reload(void) { CHECK(getpid() == gettid()); return system_properties.EnableOverrides() ? 0 : -1; } + +__BIONIC_WEAK_FOR_NATIVE_BRIDGE +int __system_properties_enable_extended_override(void) { + return system_properties.EnableExtendedOverrides() ? 0 : -1; +} diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h index 1e72bf47723..c07e3c2b59f 100644 --- a/libc/include/sys/system_properties.h +++ b/libc/include/sys/system_properties.h @@ -240,6 +240,8 @@ int __system_property_update(prop_info* _Nonnull __pi, const char* _Nonnull __va * Available since API level 35. */ int __system_properties_zygote_reload(void) __INTRODUCED_IN(35); + +int __system_properties_enable_extended_override(void); #endif /** diff --git a/libc/libc.map.txt b/libc/libc.map.txt index c77e540b4a7..ef349bb76eb 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1612,6 +1612,7 @@ LIBC_V { # introduced=35 tzfree; wcsrtombs_l; __system_properties_zygote_reload; # apex + __system_properties_enable_extended_override; # apex } LIBC_U; LIBC_36 { # introduced=36 diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h index 6c3b1cd78d9..98c4a8df921 100644 --- a/libc/system_properties/include/system_properties/system_properties.h +++ b/libc/system_properties/include/system_properties/system_properties.h @@ -53,6 +53,7 @@ class SystemProperties { bool Init(const char* filename); bool EnableOverrides(); + bool EnableExtendedOverrides(); bool AreaInit(const char* filename, bool* fsetxattr_failed); bool AreaInit(const char* filename, bool* fsetxattr_failed, bool load_default_path); uint32_t AreaSerial(); @@ -91,6 +92,7 @@ class SystemProperties { bool initialized_; bool use_appcompat_override_; + bool use_extended_override_; PropertiesFilename properties_filename_; PropertiesFilename appcompat_filename_; }; diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp index ca286e8ee78..9043af363f9 100644 --- a/libc/system_properties/system_properties.cpp +++ b/libc/system_properties/system_properties.cpp @@ -53,6 +53,7 @@ #define SERIAL_VALUE_LEN(serial) ((serial) >> 24) #define APPCOMPAT_PREFIX "ro.appcompat_override." #define APPCOMPAT_OVERRIDE_ENV_VAR "BIONIC_APPCOMPAT_OVERRIDE" +#define EXTENDED_OVERRIDE_ENV_VAR "GOS_HIDE_CARRIER_INFO_PROP_OVERRIDE" static bool is_dir(const char* pathname) { struct stat info; @@ -81,6 +82,11 @@ bool SystemProperties::Init(const char* filename) { use_appcompat_override_ = true; } + if (getenv(EXTENDED_OVERRIDE_ENV_VAR) != nullptr) { + use_appcompat_override_ = true; + use_extended_override_ = true; + } + initialized_ = true; return true; } @@ -151,6 +157,33 @@ bool SystemProperties::EnableOverrides() { return true; } +bool SystemProperties::EnableExtendedOverrides() { + CHECK(initialized_); + use_appcompat_override_ = true; + use_extended_override_ = true; + putenv(const_cast(APPCOMPAT_OVERRIDE_ENV_VAR "=1")); + putenv(const_cast(EXTENDED_OVERRIDE_ENV_VAR "=1")); + return true; +} + +static const char* const kHideCarrierInfoDeniedProps[] = { + "gsm.sim.operator.alpha", + "gsm.sim.operator.numeric", + "gsm.sim.operator.iso-country", + "gsm.operator.alpha", + "gsm.operator.numeric", + "gsm.operator.iso-country", + "gsm.operator.isroaming", + "gsm.sim.state", +}; + +static bool is_hide_carrier_info_denied(const char* name) { + for (const char* denied : kHideCarrierInfoDeniedProps) { + if (strcmp(name, denied) == 0) return true; + } + return false; +} + uint32_t SystemProperties::AreaSerial() { if (!initialized_) { return -1; @@ -170,6 +203,10 @@ const prop_info* SystemProperties::Find(const char* name) { return nullptr; } + if (use_extended_override_ && is_hide_carrier_info_denied(name)) { + return nullptr; + } + // if appcompat override is enabled, we first try finding APPCOMPAT_PREFIXed system // property if (use_appcompat_override_) { From 3a2ae1faba5f299514bb5e889e55fa41f40d05ff Mon Sep 17 00:00:00 2001 From: maade93791 <70593890+maade69@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:49:27 +0300 Subject: [PATCH 2/4] system_properties: when doing overrides update SERIAL_VALUE_LEN in new prop_info --- libc/system_properties/system_properties.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp index 9043af363f9..42483e1b761 100644 --- a/libc/system_properties/system_properties.cpp +++ b/libc/system_properties/system_properties.cpp @@ -465,6 +465,11 @@ int SystemProperties::Add(const char* name, unsigned int namelen, const char* va CHECK(getpid() == 1 || getuid() == 0); atomic_thread_fence(memory_order_release); memcpy(other_pi->value, value, valuelen + 1); + // the high byte of serial encodes value length, we need to update it so readers + // (that use SERIAL_VALUE_LEN) return the full overridden string. + uint32_t old_serial = atomic_load_explicit(&other_pi->serial, memory_order_relaxed); + uint32_t new_serial = (valuelen << 24) | (old_serial & 0x00ffffff); + atomic_store_explicit(&other_pi->serial, new_serial, memory_order_release); } } From 76fec707a38009bf134b3138ee18789d815198e7 Mon Sep 17 00:00:00 2001 From: maade93791 <70593890+maade69@users.noreply.github.com> Date: Mon, 4 May 2026 01:57:57 +0300 Subject: [PATCH 3/4] add tests for extended sysprop overrides --- tests/system_properties_test.cpp | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp index b30c8fcfb77..cf9818922b6 100644 --- a/tests/system_properties_test.cpp +++ b/tests/system_properties_test.cpp @@ -227,6 +227,71 @@ TEST(properties, __system_property_getprop_appcompat) { #endif // __BIONIC__ } +TEST(properties, __system_property_add_extended_override) { +#if defined(__BIONIC__) + SystemPropertiesTest system_properties; + ASSERT_TRUE(system_properties.valid()); + + ASSERT_EQ(0, system_properties.Add("gsm.sim.operator.numeric", 24, "123456", 6)); + ASSERT_EQ(0, system_properties.Add("ro.other.prop", 13, "value", 5)); + + char propvalue[PROP_VALUE_MAX]; + + // before enabling: denied prop is readable + ASSERT_EQ(6, system_properties.Get("gsm.sim.operator.numeric", propvalue)); + ASSERT_STREQ(propvalue, "123456"); + ASSERT_NE(nullptr, system_properties.Find("gsm.sim.operator.numeric")); + + system_properties.EnableExtendedOverrides(); + + // after enabling: denied prop hidden from Find and Get + ASSERT_EQ(nullptr, system_properties.Find("gsm.sim.operator.numeric")); + ASSERT_EQ(0, system_properties.Get("gsm.sim.operator.numeric", propvalue)); + ASSERT_STREQ(propvalue, ""); + + // non-denied prop unaffected + ASSERT_EQ(5, system_properties.Get("ro.other.prop", propvalue)); + ASSERT_STREQ(propvalue, "value"); +#else // __BIONIC__ + GTEST_SKIP() << "bionic-only test"; +#endif // __BIONIC__ +} + +TEST(properties, __system_property_update_extended_override_denylist) { +#if defined(__BIONIC__) + SystemPropertiesTest system_properties; + ASSERT_TRUE(system_properties.valid()); + + ASSERT_EQ(0, system_properties.Add("gsm.sim.operator.numeric", 24, "123456", 6)); + ASSERT_EQ(0, system_properties.Add("gsm.version.baseband", 20, "v1", 2)); + + // capture prop_info* before enabling override (Find returns nullptr afterward for denied props) + const prop_info* denied_pi = system_properties.Find("gsm.sim.operator.numeric"); + ASSERT_NE(nullptr, denied_pi); + const prop_info* allowed_pi = system_properties.Find("gsm.version.baseband"); + ASSERT_NE(nullptr, allowed_pi); + + system_properties.EnableExtendedOverrides(); + + // update underlying values (as init would) + system_properties.Update(const_cast(denied_pi), "654321", 6); + system_properties.Update(const_cast(allowed_pi), "v2", 2); + + char propvalue[PROP_VALUE_MAX]; + + // denied prop still hidden after update + ASSERT_EQ(nullptr, system_properties.Find("gsm.sim.operator.numeric")); + ASSERT_EQ(0, system_properties.Get("gsm.sim.operator.numeric", propvalue)); + ASSERT_STREQ(propvalue, ""); + + // allowed prop updated normally + ASSERT_EQ(2, system_properties.Get("gsm.version.baseband", propvalue)); + ASSERT_STREQ(propvalue, "v2"); +#else // __BIONIC__ + GTEST_SKIP() << "bionic-only test"; +#endif // __BIONIC__ +} + TEST(properties, __system_property_update) { #if defined(__BIONIC__) SystemPropertiesTest system_properties; From 99fe6153a7e9d4519d279f51f45c760bebd674b1 Mon Sep 17 00:00:00 2001 From: maade93791 <70593890+maade69@users.noreply.github.com> Date: Mon, 4 May 2026 01:58:38 +0300 Subject: [PATCH 4/4] add a seperate target for sysprop tests --- tests/Android.bp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/Android.bp b/tests/Android.bp index c5687625a8a..b806cee95d7 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -1322,6 +1322,54 @@ cc_test { ], } +// minial static binary for just the system properties tests +cc_test { + name: "bionic-sysprop-tests", + gtest: false, + defaults: [ + "bionic_tests_defaults", + "large_system_property_node_defaults", + ], + host_supported: false, + test_suites: ["general-tests"], + + srcs: [ + "gtest_globals.cpp", + "gtest_main.cpp", + "system_properties_test.cpp", + "utils.cpp", + ], + + include_dirs: [ + "bionic/libc", + ], + + target: { + bionic: { + whole_static_libs: [ + "libasync_safe", + "libprocinfo", + "libsystemproperties", + ], + }, + }, + + static_libs: [ + "libm", + "libc", + "libdl", + "liblog", + "libbase", + "libgtest_isolated", + ], + + static_executable: true, + stl: "libc++_static", + lto: { + never: true, + }, +} + // ----------------------------------------------------------------------------- // Tests to run on the host and linked against glibc. Run with: // cd bionic/tests; mm bionic-unit-tests-glibc-run