OSDN Git Service

bionic: add missing memory barriers to system properties
authorGreg Hackmann <ghackmann@google.com>
Thu, 20 Jun 2013 17:33:28 +0000 (10:33 -0700)
committerColin Cross <ccross@android.com>
Mon, 24 Jun 2013 23:35:27 +0000 (16:35 -0700)
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 5bfa3ee8b37ef162154559575193018a6235acba)

Change-Id: Id3fa45261fc2df2ae493ab5194bc2b6bff04e966

libc/bionic/system_properties.c

index 800c8b8..b12879e 100644 (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++;