Skip to content

Commit

Permalink
Fix prop override on Android V
Browse files Browse the repository at this point in the history
Change-Id: Iead5765395ffe4d8a5a8f93db4841c68e3c0b9b3
  • Loading branch information
luk1337 committed Oct 7, 2024
1 parent 37887e5 commit d11a352
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 1 deletion.
5 changes: 5 additions & 0 deletions aosp/bionic/libc/bionic/system_property_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ int __system_property_add(const char* name, unsigned int namelen, const char* va
return system_properties.Add(name, namelen, value, valuelen);
}

__BIONIC_WEAK_FOR_NATIVE_BRIDGE
int __system_property_del(const char* name) {
return system_properties.Delete(name);
}

__BIONIC_WEAK_FOR_NATIVE_BRIDGE
uint32_t __system_property_serial(const prop_info* pi) {
return system_properties.Serial(pi);
Expand Down
6 changes: 6 additions & 0 deletions aosp/bionic/libc/include/sys/_system_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ uint32_t __system_property_area_serial(void);
*/
int __system_property_add(const char* __name, unsigned int __name_length, const char* __value, unsigned int __value_length);

/* Delete a system property.
**
** Returns 0 on success, -1 if the property area is full.
*/
int __system_property_del(const char *__name);

/* Update the value of a system property returned by
** __system_property_find. Can only be done by a single process
** that has write access to the property area, and that process
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class prop_area {

const prop_info* find(const char* name);
bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
bool del(const char* name);

bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class SystemProperties {
int Get(const char* name, char* value);
int Update(prop_info* pi, const char* value, unsigned int len);
int Add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
int Delete(const char* name);
uint32_t Serial(const prop_info* pi);
uint32_t WaitAny(uint32_t old_serial);
bool Wait(const prop_info* pi, uint32_t old_serial, uint32_t* new_serial_ptr,
Expand Down
43 changes: 43 additions & 0 deletions aosp/bionic/libc/system_properties/prop_area.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,49 @@ bool prop_area::add(const char* name, unsigned int namelen, const char* value,
return find_property(root_node(), name, namelen, value, valuelen, true);
}

bool prop_area::del(const char* name) {
prop_bt* const trie = root_node();
if (!trie) return false;

const char* remaining_name = name;
prop_bt* current = trie;
while (true) {
const char* sep = strchr(remaining_name, '.');
const bool want_subtree = (sep != nullptr);
const uint32_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name);

if (!substr_size) {
return false;
}

prop_bt* root = nullptr;
uint_least32_t children_offset = atomic_load_explicit(&current->children, memory_order_relaxed);
if (children_offset != 0) {
root = to_prop_bt(&current->children);
}

if (!root) {
return false;
}

current = find_prop_bt(root, remaining_name, substr_size, false);
if (!current) {
return false;
}

if (!want_subtree) break;

remaining_name = sep + 1;
}

uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed);
if (prop_offset != 0) {
uint_least32_t new_offset = 0;
atomic_store_explicit(&current->prop, new_offset, memory_order_release);
}
return true;
}

bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
return foreach_property(root_node(), propfn, cookie);
}
30 changes: 30 additions & 0 deletions aosp/bionic/libc/system_properties/system_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,36 @@ int SystemProperties::Add(const char* name, unsigned int namelen, const char* va
return 0;
}

int SystemProperties::Delete(const char* name) {
if (!initialized_) {
return -1;
}

prop_area* serial_pa = contexts_->GetSerialPropArea();
if (serial_pa == nullptr) {
return -1;
}

prop_area* pa = contexts_->GetPropAreaForName(name);
if (!pa) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied deleting property \"%s\"", name);
return -1;
}

bool ret = pa->del(name);
if (!ret) {
return -1;
}

// There is only a single mutator, but we want to make sure that
// updates are visible to a reader waiting for the update.
atomic_store_explicit(serial_pa->serial(),
atomic_load_explicit(serial_pa->serial(), memory_order_relaxed) + 1,
memory_order_release);
__futex_wake(serial_pa->serial(), INT32_MAX);
return 0;
}

// Wait for non-locked serial, and retrieve it with acquire semantics.
uint32_t SystemProperties::Serial(const prop_info* pi) {
uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
Expand Down
3 changes: 2 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ void property_override(char const prop[], char const value[], bool add = false)
auto pi = (prop_info *) __system_property_find(prop);

if (pi != nullptr) {
__system_property_update(pi, value, strlen(value));
__system_property_del(prop);
__system_property_add(prop, strlen(prop), value, strlen(value));
} else if (add) {
__system_property_add(prop, strlen(prop), value, strlen(value));
}
Expand Down

0 comments on commit d11a352

Please sign in to comment.