Add resetprop magic

This commit is contained in:
topjohnwu 2018-09-06 02:54:51 -04:00
parent 7a0025673c
commit c0f45b6b1e
7 changed files with 76 additions and 10 deletions

View File

@ -110,6 +110,8 @@ class prop_area {
const prop_info* find(const char* name); const prop_info* find(const char* name);
bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen); 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); bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
@ -124,7 +126,7 @@ class prop_area {
} }
private: 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); 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); 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); 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 prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
const char* value, uint32_t valuelen, bool alloc_if_needed); const char* value, uint32_t valuelen, bool alloc_if_needed);

View File

@ -66,6 +66,7 @@ class SystemProperties {
int Get(const char* name, char* value); int Get(const char* name, char* value);
int Update(prop_info* pi, const char* value, unsigned int len); 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 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 Serial(const prop_info* pi);
uint32_t WaitAny(uint32_t old_serial); uint32_t WaitAny(uint32_t old_serial);
bool Wait(const prop_info* pi, uint32_t old_serial, uint32_t* new_serial_ptr, bool Wait(const prop_info* pi, uint32_t old_serial, uint32_t* new_serial_ptr,

View File

@ -104,7 +104,8 @@ prop_area* prop_area::map_prop_area_rw(const char* filename, const char* context
return pa; 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; struct stat fd_stat;
if (fstat(fd, &fd_stat) < 0) { if (fstat(fd, &fd_stat) < 0) {
return nullptr; return nullptr;
@ -119,7 +120,8 @@ prop_area* prop_area::map_fd_ro(const int fd) {
pa_size_ = fd_stat.st_size; pa_size_ = fd_stat.st_size;
pa_data_size_ = pa_size_ - sizeof(prop_area); 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) { if (map_result == MAP_FAILED) {
return nullptr; 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) { 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; if (fd == -1) return nullptr;
prop_area* map_result = map_fd_ro(fd); prop_area* map_result = map_fd_rw(fd);
close(fd); close(fd);
return map_result; 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, prop_bt *prop_area::find_prop_bt(prop_bt *const trie, const char *name, bool alloc_if_needed) {
const char* value, uint32_t valuelen,
bool alloc_if_needed) {
if (!trie) return nullptr; if (!trie) return nullptr;
const char* remaining_name = name; 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; 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(&current->prop, memory_order_relaxed); uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed);
if (prop_offset != 0) { 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); 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) { bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
return foreach_property(root_node(), propfn, cookie); return foreach_property(root_node(), propfn, cookie);
} }

View File

@ -63,7 +63,8 @@ bool SystemProperties::Init(const char* filename) {
ErrnoRestorer errno_restorer; ErrnoRestorer errno_restorer;
if (initialized_) { if (initialized_) {
contexts_->ResetAccess(); /* resetprop remove */
// contexts_->ResetAccess();
return true; return true;
} }
@ -294,6 +295,36 @@ int SystemProperties::Add(const char* name, unsigned int namelen, const char* va
return 0; 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. // Wait for non-locked serial, and retrieve it with acquire semantics.
uint32_t SystemProperties::Serial(const prop_info* pi) { uint32_t SystemProperties::Serial(const prop_info* pi) {
uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire); uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);

View File

@ -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); 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 /* Update the value of a system property returned by
** __system_property_find. Can only be done by a single process ** __system_property_find. Can only be done by a single process
** that has write access to the property area, and that process ** that has write access to the property area, and that process

View File

@ -17,6 +17,5 @@
#define __system_property_serial __system_property_serial2 #define __system_property_serial __system_property_serial2
#define __system_properties_init __system_properties_init2 #define __system_properties_init __system_properties_init2
#define __system_property_wait_any __system_property_wait_any2 #define __system_property_wait_any __system_property_wait_any2
#define __system_property_del(x) -1 /* Temp disable */
#endif //REDEFS_H #endif //REDEFS_H

View File

@ -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); 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 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
uint32_t __system_property_serial(const prop_info* pi) { uint32_t __system_property_serial(const prop_info* pi) {
return system_properties.Serial(pi); return system_properties.Serial(pi);