Merge "Remove capability setting for legacy_wifi_hal" into oc-dev
diff --git a/init/init.cpp b/init/init.cpp
index a75ced5..9cdbd19 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -850,7 +850,7 @@
     const char* compile_args[] = {
         "/system/bin/secilc",
         plat_policy_cil_file,
-        "-M", "true", "-G",
+        "-M", "true", "-G", "-N",
         // Target the highest policy language version supported by the kernel
         "-c", std::to_string(max_policy_version).c_str(),
         mapping_file.c_str(),
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 3fdf748..82954a8 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -158,7 +158,6 @@
     { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/ppp/*" },
     { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/rc.*" },
     { 00440, AID_ROOT,      AID_ROOT,      0, "system/etc/recovery.img" },
-    { 00440, AID_RADIO,     AID_ROOT,      0, "system/etc/xtables.lock" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/build.prop" },
     { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/default.prop" },
     { 00444, AID_ROOT,      AID_ROOT,      0, ven_conf_dir + 1 },
diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h
index 5f70f7d..9ece0b3 100644
--- a/liblog/include/log/log_time.h
+++ b/liblog/include/log/log_time.h
@@ -41,13 +41,12 @@
   static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
   static const uint32_t tv_nsec_max = 999999999UL;
 
-  log_time(const timespec& T) {
-    tv_sec = static_cast<uint32_t>(T.tv_sec);
-    tv_nsec = static_cast<uint32_t>(T.tv_nsec);
+  log_time(const timespec& T)
+      : tv_sec(static_cast<uint32_t>(T.tv_sec)),
+        tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {
   }
-  log_time(uint32_t sec, uint32_t nsec) {
-    tv_sec = sec;
-    tv_nsec = nsec;
+  explicit log_time(uint32_t sec, uint32_t nsec = 0)
+      : tv_sec(sec), tv_nsec(nsec) {
   }
 #ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
 #define __struct_log_time_private_defined
@@ -56,14 +55,14 @@
   log_time() {
   }
 #ifdef __linux__
-  log_time(clockid_t id) {
+  explicit log_time(clockid_t id) {
     timespec T;
     clock_gettime(id, &T);
     tv_sec = static_cast<uint32_t>(T.tv_sec);
     tv_nsec = static_cast<uint32_t>(T.tv_nsec);
   }
 #endif
-  log_time(const char* T) {
+  explicit log_time(const char* T) {
     const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
     tv_sec = c[0] | (static_cast<uint32_t>(c[1]) << 8) |
              (static_cast<uint32_t>(c[2]) << 16) |
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 70b8a28..ec32da0 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -1839,6 +1839,7 @@
   // that it can be determined the property is not set.
   static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
   char persist[PROP_VALUE_MAX];
+  char persist_hold[PROP_VALUE_MAX];
   char readonly[PROP_VALUE_MAX];
 
   // First part of this test requires the test itself to have the appropriate
@@ -1846,14 +1847,16 @@
   // bail rather than give a failing grade.
   property_get(persist_key, persist, "");
   fprintf(stderr, "INFO: getprop %s -> %s\n", persist_key, persist);
+  strncpy(persist_hold, persist, PROP_VALUE_MAX);
   property_get(readonly_key, readonly, nothing_val);
   fprintf(stderr, "INFO: getprop %s -> %s\n", readonly_key, readonly);
 
   if (!strcmp(readonly, nothing_val)) {
+    // Lets check if we can set the value (we should not be allowed to do so)
     EXPECT_FALSE(__android_log_security());
     fprintf(stderr, "WARNING: setting ro.device_owner to a domain\n");
     static const char domain[] = "com.google.android.SecOps.DeviceOwner";
-    property_set(readonly_key, domain);
+    EXPECT_NE(0, property_set(readonly_key, domain));
     useconds_t total_time = 0;
     static const useconds_t seconds = 1000000;
     static const useconds_t max_time = 5 * seconds;  // not going to happen
@@ -1870,9 +1873,12 @@
         break;
       }
     }
-    EXPECT_STREQ(readonly, domain);
-  } else if (!strcasecmp(readonly, "false") || !readonly[0]) {
-    // not enough permissions to run
+    EXPECT_STRNE(domain, readonly);
+  }
+
+  if (!strcasecmp(readonly, "false") || !readonly[0] ||
+      !strcmp(readonly, nothing_val)) {
+    // not enough permissions to run tests surrounding persist.logd.security
     EXPECT_FALSE(__android_log_security());
     return;
   }
@@ -1883,16 +1889,51 @@
     EXPECT_FALSE(__android_log_security());
   }
   property_set(persist_key, "TRUE");
-  EXPECT_TRUE(__android_log_security());
+  property_get(persist_key, persist, "");
+  uid_t uid = getuid();
+  gid_t gid = getgid();
+  bool perm = (gid == AID_ROOT) || (uid == AID_ROOT);
+  EXPECT_STREQ(perm ? "TRUE" : persist_hold, persist);
+  if (!strcasecmp(persist, "true")) {
+    EXPECT_TRUE(__android_log_security());
+  } else {
+    EXPECT_FALSE(__android_log_security());
+  }
   property_set(persist_key, "FALSE");
-  EXPECT_FALSE(__android_log_security());
+  property_get(persist_key, persist, "");
+  EXPECT_STREQ(perm ? "FALSE" : persist_hold, persist);
+  if (!strcasecmp(persist, "true")) {
+    EXPECT_TRUE(__android_log_security());
+  } else {
+    EXPECT_FALSE(__android_log_security());
+  }
   property_set(persist_key, "true");
-  EXPECT_TRUE(__android_log_security());
+  property_get(persist_key, persist, "");
+  EXPECT_STREQ(perm ? "true" : persist_hold, persist);
+  if (!strcasecmp(persist, "true")) {
+    EXPECT_TRUE(__android_log_security());
+  } else {
+    EXPECT_FALSE(__android_log_security());
+  }
   property_set(persist_key, "false");
-  EXPECT_FALSE(__android_log_security());
+  property_get(persist_key, persist, "");
+  EXPECT_STREQ(perm ? "false" : persist_hold, persist);
+  if (!strcasecmp(persist, "true")) {
+    EXPECT_TRUE(__android_log_security());
+  } else {
+    EXPECT_FALSE(__android_log_security());
+  }
   property_set(persist_key, "");
-  EXPECT_FALSE(__android_log_security());
-  property_set(persist_key, persist);
+  property_get(persist_key, persist, "");
+  EXPECT_STREQ(perm ? "" : persist_hold, persist);
+  if (!strcasecmp(persist, "true")) {
+    EXPECT_TRUE(__android_log_security());
+  } else {
+    EXPECT_FALSE(__android_log_security());
+  }
+  property_set(persist_key, persist_hold);
+  property_get(persist_key, persist, "");
+  EXPECT_STREQ(persist_hold, persist);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1eda15d..4aa2c9f 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -1120,9 +1120,22 @@
 
     log_time max = start;
 
+    LogBufferElement* lastElement = nullptr;  // iterator corruption paranoia
+    static const size_t maxSkip = 4194304;    // maximum entries to skip
+    size_t skip = maxSkip;
     for (; it != mLogElements.end(); ++it) {
         LogBufferElement* element = *it;
 
+        if (!--skip) {
+            android::prdebug("reader.per: too many elements skipped");
+            break;
+        }
+        if (element == lastElement) {
+            android::prdebug("reader.per: identical elements");
+            break;
+        }
+        lastElement = element;
+
         if (!privileged && (element->getUid() != uid)) {
             continue;
         }
@@ -1167,6 +1180,7 @@
             return max;
         }
 
+        skip = maxSkip;
         pthread_mutex_lock(&mLogElementsLock);
     }
     pthread_mutex_unlock(&mLogElementsLock);
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index ddff393..c81aa32 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -668,8 +668,12 @@
     while (--i) {
         int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
                                      SOCK_SEQPACKET);
-        EXPECT_LT(0, fd);
-        if (fd < 0) _exit(fd);
+        int save_errno = errno;
+        if (fd < 0) {
+            fprintf(stderr, "failed to open /dev/socket/logdr %s\n",
+                    strerror(save_errno));
+            _exit(fd);
+        }
 
         std::string ask = android::base::StringPrintf(
             "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32
@@ -721,8 +725,12 @@
         // active _or_ inactive during the test.
         if (content_timeout) {
             log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec);
-            EXPECT_FALSE(msg < now);
-            if (msg < now) _exit(-1);
+            if (msg < now) {
+                fprintf(stderr, "%u.%09u < %u.%09u\n", msg_timeout.entry.sec,
+                        msg_timeout.entry.nsec, (unsigned)now.tv_sec,
+                        (unsigned)now.tv_nsec);
+                _exit(-1);
+            }
             if (msg > now) {
                 now = msg;
                 now.tv_sec += 30;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index fd82513..4ebebb7 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -504,6 +504,7 @@
 on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    start netd
    start zygote
+   start zygote_secondary
 
 on boot
     # basic network init