Merge "bootstat: Remove debug logging of bootstat_mtime_matches_content."
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index b9dfedb..831150b 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -57,8 +57,9 @@
 }
 
 // Attach to a thread, and verify that it's still a member of the given process
-static bool ptrace_attach_thread(pid_t pid, pid_t tid) {
+static bool ptrace_attach_thread(pid_t pid, pid_t tid, std::string* error) {
   if (ptrace(PTRACE_ATTACH, tid, 0, 0) != 0) {
+    *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
     return false;
   }
 
@@ -67,7 +68,7 @@
     if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
       PLOG(FATAL) << "failed to detach from thread " << tid;
     }
-    errno = ECHILD;
+    *error = StringPrintf("thread %d is not in process %d", tid, pid);
     return false;
   }
   return true;
@@ -244,9 +245,9 @@
 
   check_process(target_proc_fd, target);
 
-  int attach_error = 0;
-  if (!ptrace_attach_thread(target, main_tid)) {
-    PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target;
+  std::string attach_error;
+  if (!ptrace_attach_thread(target, main_tid, &attach_error)) {
+    LOG(FATAL) << attach_error;
   }
 
   check_process(target_proc_fd, target);
@@ -268,10 +269,6 @@
     TEMP_FAILURE_RETRY(dup2(devnull.get(), STDOUT_FILENO));
   }
 
-  if (attach_error != 0) {
-    PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target;
-  }
-
   LOG(INFO) << "performing dump of process " << target << " (target tid = " << main_tid << ")";
 
   // At this point, the thread that made the request has been PTRACE_ATTACHed
@@ -307,6 +304,7 @@
   bool fatal_signal = signo != DEBUGGER_SIGNAL;
   int resume_signal = fatal_signal ? signo : 0;
   std::set<pid_t> siblings;
+  std::set<pid_t> attached_siblings;
   if (resume_signal == 0) {
     if (!android::procinfo::GetProcessTids(target, &siblings)) {
       PLOG(FATAL) << "failed to get process siblings";
@@ -314,8 +312,10 @@
     siblings.erase(main_tid);
 
     for (pid_t sibling_tid : siblings) {
-      if (!ptrace_attach_thread(target, sibling_tid)) {
-        PLOG(FATAL) << "failed to attach to thread " << main_tid << " in process " << target;
+      if (!ptrace_attach_thread(target, sibling_tid, &attach_error)) {
+        LOG(WARNING) << attach_error;
+      } else {
+        attached_siblings.insert(sibling_tid);
       }
     }
   }
@@ -328,14 +328,14 @@
   std::string amfd_data;
 
   if (backtrace) {
-    dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, siblings, 0);
+    dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0);
   } else {
     // Collect the list of open files.
     OpenFilesList open_files;
     populate_open_files_list(target, &open_files);
 
-    engrave_tombstone(output_fd.get(), backtrace_map.get(), open_files, target, main_tid, siblings,
-                      abort_address, fatal_signal ? &amfd_data : nullptr);
+    engrave_tombstone(output_fd.get(), backtrace_map.get(), open_files, target, main_tid,
+                      attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr);
   }
 
   bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false);
@@ -357,7 +357,7 @@
     }
   }
 
-  for (pid_t tid : siblings) {
+  for (pid_t tid : attached_siblings) {
     // Don't send the signal to sibling threads.
     if (ptrace(PTRACE_DETACH, tid, 0, wait_for_gdb ? SIGSTOP : 0) != 0) {
       PLOG(ERROR) << "ptrace detach from " << tid << " failed";
diff --git a/init/init.cpp b/init/init.cpp
index 75d8bc7..ddc707f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -263,26 +263,18 @@
     panic();
 }
 
-#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
-#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
-
-/* __attribute__((unused)) due to lack of mips support: see mips block
- * in set_mmap_rnd_bits_action */
-static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
-    std::string path;
-    if (compat) {
-        path = MMAP_RND_COMPAT_PATH;
-    } else {
-        path = MMAP_RND_PATH;
-    }
+static bool set_highest_available_option_value(std::string path, int min, int max)
+{
     std::ifstream inf(path, std::fstream::in);
     if (!inf) {
         LOG(ERROR) << "Cannot open for reading: " << path;
         return false;
     }
-    while (start >= min) {
+
+    int current = max;
+    while (current >= min) {
         // try to write out new value
-        std::string str_val = std::to_string(start);
+        std::string str_val = std::to_string(current);
         std::ofstream of(path, std::fstream::out);
         if (!of) {
             LOG(ERROR) << "Cannot open for writing: " << path;
@@ -298,16 +290,33 @@
         if (str_val.compare(str_rec) == 0) {
             break;
         }
-        start--;
+        current--;
     }
     inf.close();
-    if (start < min) {
-        LOG(ERROR) << "Unable to set minimum required entropy " << min << " in " << path;
+
+    if (current < min) {
+        LOG(ERROR) << "Unable to set minimum option value " << min << " in " << path;
         return false;
     }
     return true;
 }
 
+#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
+#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
+
+/* __attribute__((unused)) due to lack of mips support: see mips block
+ * in set_mmap_rnd_bits_action */
+static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
+    std::string path;
+    if (compat) {
+        path = MMAP_RND_COMPAT_PATH;
+    } else {
+        path = MMAP_RND_PATH;
+    }
+
+    return set_highest_available_option_value(path, min, start);
+}
+
 /*
  * Set /proc/sys/vm/mmap_rnd_bits and potentially
  * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
@@ -360,6 +369,25 @@
     return ret;
 }
 
+#define KPTR_RESTRICT_PATH "/proc/sys/kernel/kptr_restrict"
+#define KPTR_RESTRICT_MINVALUE 2
+#define KPTR_RESTRICT_MAXVALUE 4
+
+/* Set kptr_restrict to the highest available level.
+ *
+ * Aborts if unable to set this to an acceptable value.
+ */
+static int set_kptr_restrict_action(const std::vector<std::string>& args)
+{
+    std::string path = KPTR_RESTRICT_PATH;
+
+    if (!set_highest_available_option_value(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) {
+        LOG(ERROR) << "Unable to set adequate kptr_restrict value!";
+        security_failure();
+    }
+    return 0;
+}
+
 static int keychord_init_action(const std::vector<std::string>& args)
 {
     keychord_init();
@@ -818,6 +846,7 @@
     // ... so that we can start queuing up actions that require stuff from /dev.
     am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
     am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
+    am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict");
     am.QueueBuiltinAction(keychord_init_action, "keychord_init");
     am.QueueBuiltinAction(console_init_action, "console_init");
 
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index f19c3ab..1a2d506 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -262,6 +262,8 @@
     }
 
 #if defined(__ANDROID__)
+    clock_gettime(android_log_clockid(), &ts);
+
     if (log_id == LOG_ID_SECURITY) {
         if (vec[0].iov_len < 4) {
             return -EINVAL;
@@ -351,8 +353,6 @@
             return -EPERM;
         }
     }
-
-    clock_gettime(android_log_clockid(), &ts);
 #else
     /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
     {
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 703c0fb..13a7922 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -196,7 +196,9 @@
     EXPECT_TRUE(NULL != main_logs);
 
     char *radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
-    EXPECT_TRUE(NULL != radio_logs);
+    if (!radio_logs) GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n"
+                                         "Actual: false\n"
+                                         "Expected: false\n";
 
     char *system_logs = strstr(cp, "\nChattiest UIDs in system ");
     EXPECT_TRUE(NULL != system_logs);
@@ -942,8 +944,16 @@
         return 0;
     }
 
-    // Requests dac_read_search, falls back to request dac_override
-    rate /= 2;
+    // The key here is we are root, but we are in u:r:shell:s0,
+    // and the directory does not provide us DAC access
+    // (eg: 0700 system system) so we trigger the pair dac_override
+    // and dac_read_search on every try to get past the message
+    // de-duper.  We will also rotate the file name in the directory
+    // as another measure.
+    static const char file[] = "/data/backup/cannot_access_directory_%u";
+    static const unsigned avc_requests_per_access = 2;
+
+    rate /= avc_requests_per_access;
     useconds_t usec;
     if (rate == 0) {
         rate = 1;
@@ -951,15 +961,12 @@
     } else {
         usec = (1000000 + (rate / 2)) / rate;
     }
-    num = (num + 1) / 2;
+    num = (num + (avc_requests_per_access / 2)) / avc_requests_per_access;
 
     if (usec < 2) usec = 2;
 
     while (num > 0) {
-        if (access(android::base::StringPrintf(
-                       "/data/misc/logd/cannot_access_directory_%u",
-                       num).c_str(),
-                   F_OK) == 0) {
+        if (access(android::base::StringPrintf(file, num).c_str(), F_OK) == 0) {
             _exit(-1);
             // NOTREACHED
             return 0;
@@ -1002,7 +1009,7 @@
 
         // int len = get4LE(eventData + 4 + 1);
         log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0';
-        const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: ");
+        const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: denied");
         if (!cp) continue;
 
         ++count;
@@ -1055,8 +1062,7 @@
     // give logd another 3 seconds to react to the burst before checking
     sepolicy_rate(rate, rate * 3);
     // maximum period at double the maximum burst rate (spam filter kicked in)
-    EXPECT_GE(((AUDIT_RATE_LIMIT_MAX * AUDIT_RATE_LIMIT_BURST_DURATION) * 130) /
-                                        100, // +30% margin
+    EXPECT_GE(threshold * 2,
               count_avc(sepolicy_rate(rate,
                                       rate * AUDIT_RATE_LIMIT_BURST_DURATION)));
     // cool down, and check unspammy rate still works
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 791d67f..998e064 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -118,7 +118,6 @@
     write /proc/sys/kernel/sched_child_runs_first 0
 
     write /proc/sys/kernel/randomize_va_space 2
-    write /proc/sys/kernel/kptr_restrict 2
     write /proc/sys/vm/mmap_min_addr 32768
     write /proc/sys/net/ipv4/ping_group_range "0 2147483647"
     write /proc/sys/net/unix/max_dgram_qlen 600