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:
Greg Hackmann 2013-06-20 10:33:28 -07:00 committed by Colin Cross
parent cb215a7e9e
commit f7511e3bc9

View File

@ -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++;