bionic: add missing memory barriers to system properties
1) Reading the value must finish before checking whether it's intact
2) Setting the serial's dirty bit must visible before modifying the
value
3) The modified value must be visible before clearing the serial's dirty
bit
4) New properties and their TOC entries must be visible before updating
the property count
Signed-off-by: Greg Hackmann <ghackmann@google.com>
(cherry picked from commit 5bfa3ee8b3
)
Change-Id: Id3fa45261fc2df2ae493ab5194bc2b6bff04e966
This commit is contained in:
parent
cb215a7e9e
commit
f7511e3bc9
@ -49,6 +49,7 @@
|
||||
#include <sys/_system_properties.h>
|
||||
|
||||
#include <sys/atomics.h>
|
||||
#include <bionic_atomic_inline.h>
|
||||
|
||||
struct prop_area {
|
||||
unsigned volatile count;
|
||||
@ -315,6 +316,7 @@ int __system_property_read(const prop_info *pi, char *name, char *value)
|
||||
}
|
||||
len = SERIAL_VALUE_LEN(serial);
|
||||
memcpy(value, pi->value, len + 1);
|
||||
ANDROID_MEMBAR_FULL();
|
||||
if(serial == pi->serial) {
|
||||
if(name != 0) {
|
||||
strcpy(name, pi->name);
|
||||
@ -446,7 +448,9 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len)
|
||||
return -1;
|
||||
|
||||
pi->serial = pi->serial | 1;
|
||||
ANDROID_MEMBAR_FULL();
|
||||
memcpy(pi->value, value, len + 1);
|
||||
ANDROID_MEMBAR_FULL();
|
||||
pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff);
|
||||
__futex_wake(&pi->serial, INT32_MAX);
|
||||
|
||||
@ -493,6 +497,7 @@ int __system_property_add(const char *name, unsigned int namelen,
|
||||
memcpy(pi->value, value, valuelen + 1);
|
||||
|
||||
pa->toc[pa->count] = (namelen << 24) | (((unsigned) pi) - ((unsigned) pa));
|
||||
ANDROID_MEMBAR_FULL();
|
||||
|
||||
pa->count++;
|
||||
pa->serial++;
|
||||
|
Loading…
Reference in New Issue
Block a user