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"