From c0f45b6b1e3a598dba79f1f6c3fb956c4f6045b2 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 6 Sep 2018 02:54:51 -0400 Subject: [PATCH] Add resetprop magic --- .../include/system_properties/prop_area.h | 7 +++- .../system_properties/system_properties.h | 1 + .../libsystemproperties/prop_area.cpp | 33 +++++++++++++++---- .../libsystemproperties/system_properties.cpp | 33 ++++++++++++++++++- .../resetprop/private/_system_properties.h | 6 ++++ native/jni/resetprop/private/redefs.h | 1 - native/jni/resetprop/system_property_api.cpp | 5 +++ 7 files changed, 76 insertions(+), 10 deletions(-) diff --git a/native/jni/resetprop/libsystemproperties/include/system_properties/prop_area.h b/native/jni/resetprop/libsystemproperties/include/system_properties/prop_area.h index 2c253370e..9c78f1b3e 100644 --- a/native/jni/resetprop/libsystemproperties/include/system_properties/prop_area.h +++ b/native/jni/resetprop/libsystemproperties/include/system_properties/prop_area.h @@ -110,6 +110,8 @@ class prop_area { const prop_info* find(const char* name); bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen); + /* resetprop */ + bool del(const char *name); bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie); @@ -124,7 +126,7 @@ class prop_area { } private: - static prop_area* map_fd_ro(const int fd); + static prop_area* map_fd_rw(const int fd); void* allocate_obj(const size_t size, uint_least32_t* const off); prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off); @@ -138,6 +140,9 @@ class prop_area { prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed); + /* resetprop: Traverse through the trie and find the node */ + prop_bt *find_prop_bt(prop_bt *const trie, const char *name, bool alloc_if_needed); + const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen, const char* value, uint32_t valuelen, bool alloc_if_needed); diff --git a/native/jni/resetprop/libsystemproperties/include/system_properties/system_properties.h b/native/jni/resetprop/libsystemproperties/include/system_properties/system_properties.h index 52ffcafd0..9b4c48668 100644 --- a/native/jni/resetprop/libsystemproperties/include/system_properties/system_properties.h +++ b/native/jni/resetprop/libsystemproperties/include/system_properties/system_properties.h @@ -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, diff --git a/native/jni/resetprop/libsystemproperties/prop_area.cpp b/native/jni/resetprop/libsystemproperties/prop_area.cpp index 42bee9f3e..ec4aeadb1 100644 --- a/native/jni/resetprop/libsystemproperties/prop_area.cpp +++ b/native/jni/resetprop/libsystemproperties/prop_area.cpp @@ -104,7 +104,8 @@ prop_area* prop_area::map_prop_area_rw(const char* filename, const char* context return pa; } -prop_area* prop_area::map_fd_ro(const int fd) { +/* resetprop: map_fd_ro -> map_fd_rw */ +prop_area* prop_area::map_fd_rw(const int fd) { struct stat fd_stat; if (fstat(fd, &fd_stat) < 0) { return nullptr; @@ -119,7 +120,8 @@ prop_area* prop_area::map_fd_ro(const int fd) { pa_size_ = fd_stat.st_size; pa_data_size_ = pa_size_ - sizeof(prop_area); - void* const map_result = mmap(nullptr, pa_size_, PROT_READ, MAP_SHARED, fd, 0); + /* resetprop: add PROT_WRITE */ + void* const map_result = mmap(nullptr, pa_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map_result == MAP_FAILED) { return nullptr; } @@ -134,10 +136,11 @@ prop_area* prop_area::map_fd_ro(const int fd) { } prop_area* prop_area::map_prop_area(const char* filename) { - int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY); + /* resetprop: O_RDONLY -> O_RDWR */ + int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR); if (fd == -1) return nullptr; - prop_area* map_result = map_fd_ro(fd); + prop_area* map_result = map_fd_rw(fd); close(fd); return map_result; @@ -272,9 +275,7 @@ prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t n } } -const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen, - const char* value, uint32_t valuelen, - bool alloc_if_needed) { +prop_bt *prop_area::find_prop_bt(prop_bt *const trie, const char *name, bool alloc_if_needed) { if (!trie) return nullptr; const char* remaining_name = name; @@ -313,6 +314,16 @@ const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, remaining_name = sep + 1; } + return current; +} + +const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen, + const char* value, uint32_t valuelen, + bool alloc_if_needed) { + const char* remaining_name = name; + prop_bt* current = find_prop_bt(trie, name, alloc_if_needed); + if (!current) + return nullptr; uint_least32_t prop_offset = atomic_load_explicit(¤t->prop, memory_order_relaxed); if (prop_offset != 0) { @@ -368,6 +379,14 @@ 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* node = find_prop_bt(root_node(), name, false); + if (!node) + return false; + atomic_store_explicit(&node->prop, 0, 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); } diff --git a/native/jni/resetprop/libsystemproperties/system_properties.cpp b/native/jni/resetprop/libsystemproperties/system_properties.cpp index d7c441b9b..f03bfb9d4 100644 --- a/native/jni/resetprop/libsystemproperties/system_properties.cpp +++ b/native/jni/resetprop/libsystemproperties/system_properties.cpp @@ -63,7 +63,8 @@ bool SystemProperties::Init(const char* filename) { ErrnoRestorer errno_restorer; if (initialized_) { - contexts_->ResetAccess(); + /* resetprop remove */ + // contexts_->ResetAccess(); return true; } @@ -294,6 +295,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 adding 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); diff --git a/native/jni/resetprop/private/_system_properties.h b/native/jni/resetprop/private/_system_properties.h index 1b5871309..f9a22df83 100644 --- a/native/jni/resetprop/private/_system_properties.h +++ b/native/jni/resetprop/private/_system_properties.h @@ -105,6 +105,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. Added in resetprop +** +** 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 diff --git a/native/jni/resetprop/private/redefs.h b/native/jni/resetprop/private/redefs.h index 6e6e7cec9..61b7a8e81 100644 --- a/native/jni/resetprop/private/redefs.h +++ b/native/jni/resetprop/private/redefs.h @@ -17,6 +17,5 @@ #define __system_property_serial __system_property_serial2 #define __system_properties_init __system_properties_init2 #define __system_property_wait_any __system_property_wait_any2 -#define __system_property_del(x) -1 /* Temp disable */ #endif //REDEFS_H diff --git a/native/jni/resetprop/system_property_api.cpp b/native/jni/resetprop/system_property_api.cpp index 15e9d36bf..e2c5471d1 100644 --- a/native/jni/resetprop/system_property_api.cpp +++ b/native/jni/resetprop/system_property_api.cpp @@ -99,6 +99,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);