Merge "introduce auditctl and use it to configure SELinux throttling"
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
index e9d9c63..3c8f393 100644
--- a/adb/daemon/shell_service.cpp
+++ b/adb/daemon/shell_service.cpp
@@ -406,11 +406,16 @@
                                              strerror(errno));
         return false;
     }
-    // Raw subprocess + shell protocol allows for splitting stderr.
-    if (!CreateSocketpair(&stderr_sfd_, &child_stderr_sfd)) {
-        *error = android::base::StringPrintf("failed to create socketpair for stderr: %s",
-                                             strerror(errno));
-        return false;
+    if (protocol_ == SubprocessProtocol::kShell) {
+        // Shell protocol allows for splitting stderr.
+        if (!CreateSocketpair(&stderr_sfd_, &child_stderr_sfd)) {
+            *error = android::base::StringPrintf("failed to create socketpair for stderr: %s",
+                                                 strerror(errno));
+            return false;
+        }
+    } else {
+        // Raw protocol doesn't support multiple output streams, so combine stdout and stderr.
+        child_stderr_sfd.reset(dup(child_stdinout_sfd));
     }
 
     D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
diff --git a/adb/daemon/shell_service_test.cpp b/adb/daemon/shell_service_test.cpp
index 323bcec..dc79d12 100644
--- a/adb/daemon/shell_service_test.cpp
+++ b/adb/daemon/shell_service_test.cpp
@@ -35,7 +35,6 @@
     static void SetUpTestCase() {
         // This is normally done in main.cpp.
         saved_sigpipe_handler_ = signal(SIGPIPE, SIG_IGN);
-
     }
 
     static void TearDownTestCase() {
@@ -49,26 +48,32 @@
                              SubprocessProtocol protocol);
     void CleanupTestSubprocess();
 
-    virtual void TearDown() override {
-        void CleanupTestSubprocess();
-    }
+    void StartTestCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
+
+    virtual void TearDown() override { CleanupTestSubprocess(); }
 
     static sighandler_t saved_sigpipe_handler_;
 
-    unique_fd subprocess_fd_;
+    unique_fd command_fd_;
 };
 
 sighandler_t ShellServiceTest::saved_sigpipe_handler_ = nullptr;
 
 void ShellServiceTest::StartTestSubprocess(
         const char* command, SubprocessType type, SubprocessProtocol protocol) {
-    subprocess_fd_ = StartSubprocess(command, nullptr, type, protocol);
-    ASSERT_TRUE(subprocess_fd_ >= 0);
+    command_fd_ = StartSubprocess(command, nullptr, type, protocol);
+    ASSERT_TRUE(command_fd_ >= 0);
 }
 
 void ShellServiceTest::CleanupTestSubprocess() {
 }
 
+void ShellServiceTest::StartTestCommandInProcess(std::string name, Command command,
+                                                 SubprocessProtocol protocol) {
+    command_fd_ = StartCommandInProcess(std::move(name), std::move(command), protocol);
+    ASSERT_TRUE(command_fd_ >= 0);
+}
+
 namespace {
 
 // Reads raw data from |fd| until it closes or errors.
@@ -93,7 +98,7 @@
     stdout->clear();
     stderr->clear();
 
-    ShellProtocol* protocol = new ShellProtocol(fd);
+    auto protocol = std::make_unique<ShellProtocol>(fd);
     while (protocol->Read()) {
         switch (protocol->id()) {
             case ShellProtocol::kIdStdout:
@@ -111,7 +116,6 @@
                 ADD_FAILURE() << "Unidentified packet ID: " << protocol->id();
         }
     }
-    delete protocol;
 
     return exit_code;
 }
@@ -154,7 +158,7 @@
 
     // [ -t 0 ] == 0 means we have a terminal (PTY). Even when requesting a raw subprocess, without
     // the shell protocol we should always force a PTY to ensure proper cleanup.
-    ExpectLinesEqual(ReadRaw(subprocess_fd_), {"foo", "bar", "0"});
+    ExpectLinesEqual(ReadRaw(command_fd_), {"foo", "bar", "0"});
 }
 
 // Tests a PTY subprocess with no protocol.
@@ -165,7 +169,7 @@
             SubprocessType::kPty, SubprocessProtocol::kNone));
 
     // [ -t 0 ] == 0 means we have a terminal (PTY).
-    ExpectLinesEqual(ReadRaw(subprocess_fd_), {"foo", "bar", "0"});
+    ExpectLinesEqual(ReadRaw(command_fd_), {"foo", "bar", "0"});
 }
 
 // Tests a raw subprocess with the shell protocol.
@@ -175,7 +179,7 @@
             SubprocessType::kRaw, SubprocessProtocol::kShell));
 
     std::string stdout, stderr;
-    EXPECT_EQ(24, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(24, ReadShellProtocol(command_fd_, &stdout, &stderr));
     ExpectLinesEqual(stdout, {"foo", "baz"});
     ExpectLinesEqual(stderr, {"bar"});
 }
@@ -189,7 +193,7 @@
     // PTY always combines stdout and stderr but the shell protocol should
     // still give us an exit code.
     std::string stdout, stderr;
-    EXPECT_EQ(50, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(50, ReadShellProtocol(command_fd_, &stdout, &stderr));
     ExpectLinesEqual(stdout, {"foo", "bar", "baz"});
     ExpectLinesEqual(stderr, {});
 }
@@ -204,7 +208,7 @@
                               "echo --${TEST_STR}--",
                               "exit"};
 
-    ShellProtocol* protocol = new ShellProtocol(subprocess_fd_);
+    ShellProtocol* protocol = new ShellProtocol(command_fd_);
     for (std::string command : commands) {
         // Interactive shell requires a newline to complete each command.
         command.push_back('\n');
@@ -214,7 +218,7 @@
     delete protocol;
 
     std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
     // An unpredictable command prompt makes parsing exact output difficult but
     // it should at least contain echoed input and the expected output.
     for (const char* command : commands) {
@@ -230,14 +234,14 @@
             SubprocessType::kRaw, SubprocessProtocol::kShell));
 
     std::string input = "foo\nbar";
-    ShellProtocol* protocol = new ShellProtocol(subprocess_fd_);
+    ShellProtocol* protocol = new ShellProtocol(command_fd_);
     memcpy(protocol->data(), input.data(), input.length());
     ASSERT_TRUE(protocol->Write(ShellProtocol::kIdStdin, input.length()));
     ASSERT_TRUE(protocol->Write(ShellProtocol::kIdCloseStdin, 0));
     delete protocol;
 
     std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
     ExpectLinesEqual(stdout, {"foo", "barTEST_DONE"});
     ExpectLinesEqual(stderr, {});
 }
@@ -249,7 +253,7 @@
             SubprocessType::kRaw, SubprocessProtocol::kShell));
 
     std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
     ExpectLinesEqual(stdout, {});
     ExpectLinesEqual(stderr, {"bar"});
 }
@@ -261,7 +265,56 @@
             SubprocessType::kRaw, SubprocessProtocol::kShell));
 
     std::string stdout, stderr;
-    EXPECT_EQ(0, ReadShellProtocol(subprocess_fd_, &stdout, &stderr));
+    EXPECT_EQ(0, ReadShellProtocol(command_fd_, &stdout, &stderr));
     ExpectLinesEqual(stdout, {"foo"});
     ExpectLinesEqual(stderr, {});
 }
+
+// Tests an inprocess command with no protocol.
+TEST_F(ShellServiceTest, RawNoProtocolInprocess) {
+    ASSERT_NO_FATAL_FAILURE(
+            StartTestCommandInProcess("123",
+                                      [](auto args, auto in, auto out, auto err) -> int {
+                                          EXPECT_EQ("123", args);
+                                          char input[10];
+                                          EXPECT_TRUE(ReadFdExactly(in, input, 2));
+                                          input[2] = 0;
+                                          EXPECT_STREQ("in", input);
+                                          WriteFdExactly(out, "out\n");
+                                          WriteFdExactly(err, "err\n");
+                                          return 0;
+                                      },
+                                      SubprocessProtocol::kNone));
+
+    WriteFdExactly(command_fd_, "in");
+    ExpectLinesEqual(ReadRaw(command_fd_), {"out", "err"});
+}
+
+// Tests an inprocess command with the shell protocol.
+TEST_F(ShellServiceTest, RawShellProtocolInprocess) {
+    ASSERT_NO_FATAL_FAILURE(
+            StartTestCommandInProcess("321",
+                                      [](auto args, auto in, auto out, auto err) -> int {
+                                          EXPECT_EQ("321", args);
+                                          char input[10];
+                                          EXPECT_TRUE(ReadFdExactly(in, input, 2));
+                                          input[2] = 0;
+                                          EXPECT_STREQ("in", input);
+                                          WriteFdExactly(out, "out\n");
+                                          WriteFdExactly(err, "err\n");
+                                          return 0;
+                                      },
+                                      SubprocessProtocol::kShell));
+
+    {
+        auto write_protocol = std::make_unique<ShellProtocol>(command_fd_);
+        memcpy(write_protocol->data(), "in", 2);
+        write_protocol->Write(ShellProtocol::kIdStdin, 2);
+    }
+
+    std::string stdout, stderr;
+    // For in-process commands the exit code is always the default (1).
+    EXPECT_EQ(1, ReadShellProtocol(command_fd_, &stdout, &stderr));
+    ExpectLinesEqual(stdout, {"out"});
+    ExpectLinesEqual(stderr, {"err"});
+}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index dea4844..730d3db 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -715,7 +715,7 @@
     }
 
     if (changed || partition_create) {
-        if (!CreateLogicalPartition(super_device, slot_number, partition_name, true, 0s,
+        if (!CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s,
                                     scratch_device))
             return false;
 
@@ -940,7 +940,7 @@
             auto slot_number = fs_mgr_overlayfs_slot_number();
             auto super_device = fs_mgr_overlayfs_super_device(slot_number);
             const auto partition_name = android::base::Basename(kScratchMountPoint);
-            CreateLogicalPartition(super_device, slot_number, partition_name, true, 0s,
+            CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s,
                                    &scratch_device);
         }
         mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device,
diff --git a/fs_mgr/libfiemap_writer/Android.mk b/fs_mgr/libfiemap_writer/Android.mk
new file mode 100644
index 0000000..4aa2027
--- /dev/null
+++ b/fs_mgr/libfiemap_writer/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsFiemapWriterTest
+include test/vts/tools/build/Android.host_config.mk
diff --git a/fs_mgr/libfiemap_writer/AndroidTest.xml b/fs_mgr/libfiemap_writer/AndroidTest.xml
new file mode 100644
index 0000000..08cff0e
--- /dev/null
+++ b/fs_mgr/libfiemap_writer/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsFiemapWriterTest">
+    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+      <option name="test-module-name" value="VtsFiemapWriterTest"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/fiemap_writer_test/fiemap_writer_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/fiemap_writer_test/fiemap_writer_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="1m"/>
+    </test>
+</configuration>
diff --git a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
index ca51689..dda7dfd 100644
--- a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
+++ b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
@@ -498,17 +498,22 @@
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
-    if (argc <= 1) {
-        cerr << "Usage: <test_dir> [file_size]\n";
+    if (argc > 1 && argv[1] == "-h"s) {
+        cerr << "Usage: [test_dir] [file_size]\n";
         cerr << "\n";
         cerr << "Note: test_dir must be a writable, unencrypted directory.\n";
         exit(EXIT_FAILURE);
     }
     ::android::base::InitLogging(argv, ::android::base::StderrLogger);
 
-    std::string tempdir = argv[1] + "/XXXXXX"s;
+    std::string root_dir = "/data/local/unencrypted";
+    if (access(root_dir.c_str(), F_OK)) {
+        root_dir = "/data";
+    }
+
+    std::string tempdir = root_dir + "/XXXXXX"s;
     if (!mkdtemp(tempdir.data())) {
-        cerr << "unable to create tempdir on " << argv[1] << "\n";
+        cerr << "unable to create tempdir on " << root_dir << "\n";
         exit(EXIT_FAILURE);
     }
     if (!android::base::Realpath(tempdir, &gTestDir)) {
diff --git a/libmeminfo/tools/procrank.cpp b/libmeminfo/tools/procrank.cpp
index 21a684c..5e89254 100644
--- a/libmeminfo/tools/procrank.cpp
+++ b/libmeminfo/tools/procrank.cpp
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <dirent.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <linux/kernel-page-flags.h>
 #include <linux/oom.h>
+#include <meminfo/procmeminfo.h>
+#include <meminfo/sysmeminfo.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -29,14 +35,6 @@
 #include <sstream>
 #include <vector>
 
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include <meminfo/procmeminfo.h>
-#include <meminfo/sysmeminfo.h>
-
 using ::android::meminfo::MemUsage;
 using ::android::meminfo::ProcMemInfo;
 
@@ -460,8 +458,16 @@
     auto mark_swap_usage = [&](pid_t pid) -> bool {
         ProcessRecord proc(pid, show_wss, pgflags, pgflags_mask);
         if (!proc.valid()) {
-            std::cerr << "Failed to create process record for: " << pid << std::endl;
-            return false;
+            // Check to see if the process is still around, skip the process if the proc
+            // directory is inaccessible. It was most likely killed while creating the process
+            // record
+            std::string procdir = ::android::base::StringPrintf("/proc/%d", pid);
+            if (access(procdir.c_str(), F_OK | R_OK)) return true;
+
+            // Warn if we failed to gather process stats even while it is still alive.
+            // Return success here, so we continue to print stats for other processes.
+            std::cerr << "warning: failed to create process record for: " << pid << std::endl;
+            return true;
         }
 
         // Skip processes with no memory mappings
@@ -479,9 +485,9 @@
         return true;
     };
 
-    // Get a list of all pids currently running in the system in
-    // 1st pass through all processes. Mark each swap offset used by the process as we find them
-    // for calculating proportional swap usage later.
+    // Get a list of all pids currently running in the system in 1st pass through all processes.
+    // Mark each swap offset used by the process as we find them for calculating proportional
+    // swap usage later.
     if (!read_all_pids(&pids, mark_swap_usage)) {
         std::cerr << "Failed to read all pids from the system" << std::endl;
         exit(EXIT_FAILURE);
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index 6756007..cc059d8 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <error.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <getopt.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -52,9 +53,21 @@
 static uint64_t total_compressed_length = 0;
 static size_t file_count = 0;
 
-static bool Filter(const std::string& name) {
-  if (!excludes.empty() && excludes.find(name) != excludes.end()) return true;
-  if (!includes.empty() && includes.find(name) == includes.end()) return true;
+static bool ShouldInclude(const std::string& name) {
+  // Explicitly excluded?
+  if (!excludes.empty()) {
+    for (const auto& exclude : excludes) {
+      if (!fnmatch(exclude.c_str(), name.c_str(), 0)) return false;
+    }
+  }
+
+  // Implicitly included?
+  if (includes.empty()) return true;
+
+  // Explicitly included?
+  for (const auto& include : includes) {
+    if (!fnmatch(include.c_str(), name.c_str(), 0)) return true;
+  }
   return false;
 }
 
@@ -245,7 +258,7 @@
   ZipString string;
   while ((err = Next(cookie, &entry, &string)) >= 0) {
     std::string name(string.name, string.name + string.name_length);
-    if (!Filter(name)) ProcessOne(zah, entry, name);
+    if (ShouldInclude(name)) ProcessOne(zah, entry, name);
   }
 
   if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err));
@@ -260,7 +273,8 @@
 
   printf(
       "\n"
-      "Extract FILEs from ZIP archive. Default is all files.\n"
+      "Extract FILEs from ZIP archive. Default is all files. Both the include and\n"
+      "exclude (-x) lists use shell glob patterns.\n"
       "\n"
       "-d DIR	Extract into DIR\n"
       "-l	List contents (-lq excludes archive name, -lv is verbose)\n"