Merge "Improve crasher."
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index ff2d76d..ec9b1c3 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -207,11 +207,6 @@
}
if (S_ISREG(st.st_mode)) {
- if (!android::base::EndsWith(path, ".adb_key")) {
- LOG(INFO) << "skipping non-adb_key '" << path << "'";
- return false;
- }
-
return read_key_file(path);
} else if (S_ISDIR(st.st_mode)) {
if (!allow_dir) {
@@ -236,7 +231,12 @@
continue;
}
- result |= read_keys((path + OS_PATH_SEPARATOR + name).c_str(), false);
+ if (!android::base::EndsWith(name, ".adb_key")) {
+ LOG(INFO) << "skipping non-adb_key '" << path << "/" << name << "'";
+ continue;
+ }
+
+ result |= read_key_file((path + OS_PATH_SEPARATOR + name));
}
return result;
}
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 76119ef..271943d 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -720,13 +720,7 @@
}
static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath,
- const char* name=nullptr) {
- struct stat st;
- if (!sync_stat_fallback(sc, rpath, &st)) {
- sc.Error("stat failed when trying to receive %s: %s", rpath, strerror(errno));
- return false;
- }
-
+ const char* name, uint64_t expected_size) {
if (!sc.SendRequest(ID_RECV, rpath)) return false;
adb_unlink(lpath);
@@ -778,7 +772,7 @@
bytes_copied += msg.data.size;
sc.RecordBytesTransferred(msg.data.size);
- sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, st.st_size);
+ sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, expected_size);
}
sc.RecordFilesTransferred(1);
@@ -1121,7 +1115,7 @@
continue;
}
- if (!sync_recv(sc, ci.rpath.c_str(), ci.lpath.c_str())) {
+ if (!sync_recv(sc, ci.rpath.c_str(), ci.lpath.c_str(), nullptr, ci.size)) {
return false;
}
@@ -1232,7 +1226,7 @@
sc.NewTransfer();
sc.SetExpectedTotalBytes(src_st.st_size);
- if (!sync_recv(sc, src_path, dst_path, name)) {
+ if (!sync_recv(sc, src_path, dst_path, name, src_st.st_size)) {
success = false;
continue;
}
diff --git a/base/include/android-base/properties.h b/base/include/android-base/properties.h
index 95d1b6a..4d7082a 100644
--- a/base/include/android-base/properties.h
+++ b/base/include/android-base/properties.h
@@ -61,4 +61,4 @@
} // namespace base
} // namespace android
-#endif // ANDROID_BASE_MEMORY_H
+#endif // ANDROID_BASE_PROPERTIES_H
diff --git a/include/cutils/multiuser.h b/include/cutils/multiuser.h
index 7e7f815..4f23776 100644
--- a/include/cutils/multiuser.h
+++ b/include/cutils/multiuser.h
@@ -23,19 +23,19 @@
extern "C" {
#endif
-// NOTE: keep in sync with android.os.UserId
-
-#define MULTIUSER_APP_PER_USER_RANGE 100000
-#define MULTIUSER_FIRST_SHARED_APPLICATION_GID 50000
-#define MULTIUSER_FIRST_APPLICATION_UID 10000
-
typedef uid_t userid_t;
typedef uid_t appid_t;
extern userid_t multiuser_get_user_id(uid_t uid);
extern appid_t multiuser_get_app_id(uid_t uid);
-extern uid_t multiuser_get_uid(userid_t userId, appid_t appId);
-extern appid_t multiuser_get_shared_app_gid(uid_t uid);
+
+extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id);
+
+extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id);
+extern gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id);
+
+/* TODO: switch callers over to multiuser_get_shared_gid() */
+extern gid_t multiuser_get_shared_app_gid(uid_t uid);
#ifdef __cplusplus
}
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 3031562..f7cf9b8 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -157,15 +157,21 @@
#define AID_MISC 9998 /* access to misc storage */
#define AID_NOBODY 9999
-#define AID_APP 10000 /* first app user */
+#define AID_APP 10000 /* TODO: switch users over to AID_APP_START */
+#define AID_APP_START 10000 /* first app user */
+#define AID_APP_END 19999 /* last app user */
-#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
-#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
-
-#define AID_USER 100000 /* offset for uid ranges for each user */
+#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */
+#define AID_CACHE_GID_END 29999 /* end of gids for apps to mark cached data */
#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
-#define AID_SHARED_GID_END 59999 /* start of gids for apps in each user to share */
+#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */
+
+#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
+#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
+
+#define AID_USER 100000 /* TODO: switch users over to AID_USER_OFFSET */
+#define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */
#if !defined(EXCLUDE_FS_CONFIG_STRUCTURES)
/*
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 42dd0c6..cf8b274 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -559,7 +559,7 @@
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
- ret = wipe_data_via_recovery("wipe_data_via_recovery");
+ ret = wipe_data_via_recovery("fs_mgr_mount_all");
/* If reboot worked, there is no return. */
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (e4crypt_install_keyring()) {
diff --git a/init/init.cpp b/init/init.cpp
index 75b36cf..2d474c7 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -352,10 +352,6 @@
LOG(ERROR) << "Unknown architecture";
#endif
-#ifdef __BRILLO__
- // TODO: b/27794137
- ret = 0;
-#endif
if (ret == -1) {
LOG(ERROR) << "Unable to set adequate mmap entropy value!";
security_failure();
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 882d545..8fb2dbc 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -23,6 +23,7 @@
#include <algorithm>
#include <type_traits>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
@@ -34,57 +35,65 @@
"FuseBuffer must be standard layout union.");
template <typename T>
-bool FuseMessage<T>::CheckPacketSize(size_t size, const char* name) const {
+bool FuseMessage<T>::CheckHeaderLength(const char* name) const {
const auto& header = static_cast<const T*>(this)->header;
- if (size >= sizeof(header) && size <= sizeof(T)) {
+ if (header.len >= sizeof(header) && header.len <= sizeof(T)) {
return true;
} else {
- LOG(ERROR) << name << " is invalid=" << size;
- return false;
- }
-}
-
-template <typename T>
-bool FuseMessage<T>::CheckResult(int result, const char* operation_name) const {
- if (result == 0) {
- // Expected close of other endpoints.
- return false;
- }
- if (result < 0) {
- PLOG(ERROR) << "Failed to " << operation_name << " a packet";
- return false;
- }
- return true;
-}
-
-template <typename T>
-bool FuseMessage<T>::CheckHeaderLength(int result, const char* operation_name) const {
- const auto& header = static_cast<const T*>(this)->header;
- if (static_cast<uint32_t>(result) == header.len) {
- return true;
- } else {
- LOG(ERROR) << "Invalid header length: operation_name=" << operation_name
- << " result=" << result
- << " header.len=" << header.len;
+ LOG(ERROR) << "Invalid header length is found in " << name << ": " <<
+ header.len;
return false;
}
}
template <typename T>
bool FuseMessage<T>::Read(int fd) {
- const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, this, sizeof(T)));
- return CheckResult(result, "read") && CheckPacketSize(result, "read count") &&
- CheckHeaderLength(result, "read");
+ char* const buf = reinterpret_cast<char*>(this);
+ const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, buf, sizeof(T)));
+ if (result < 0) {
+ PLOG(ERROR) << "Failed to read a FUSE message";
+ return false;
+ }
+
+ const auto& header = static_cast<const T*>(this)->header;
+ if (result < static_cast<ssize_t>(sizeof(header))) {
+ LOG(ERROR) << "Read bytes " << result << " are shorter than header size " <<
+ sizeof(header);
+ return false;
+ }
+
+ if (!CheckHeaderLength("Read")) {
+ return false;
+ }
+
+ if (static_cast<uint32_t>(result) > header.len) {
+ LOG(ERROR) << "Read bytes " << result << " are longer than header.len " <<
+ header.len;
+ return false;
+ }
+
+ if (!base::ReadFully(fd, buf + result, header.len - result)) {
+ PLOG(ERROR) << "ReadFully failed";
+ return false;
+ }
+
+ return true;
}
template <typename T>
bool FuseMessage<T>::Write(int fd) const {
- const auto& header = static_cast<const T*>(this)->header;
- if (!CheckPacketSize(header.len, "header.len")) {
+ if (!CheckHeaderLength("Write")) {
return false;
}
- const ssize_t result = TEMP_FAILURE_RETRY(::write(fd, this, header.len));
- return CheckResult(result, "write") && CheckHeaderLength(result, "write");
+
+ const char* const buf = reinterpret_cast<const char*>(this);
+ const auto& header = static_cast<const T*>(this)->header;
+ if (!base::WriteFully(fd, buf, header.len)) {
+ PLOG(ERROR) << "WriteFully failed";
+ return false;
+ }
+
+ return true;
}
template class FuseMessage<FuseRequest>;
diff --git a/libappfuse/include/libappfuse/FuseBuffer.h b/libappfuse/include/libappfuse/FuseBuffer.h
index 276db90..7abd2fa 100644
--- a/libappfuse/include/libappfuse/FuseBuffer.h
+++ b/libappfuse/include/libappfuse/FuseBuffer.h
@@ -34,9 +34,7 @@
bool Read(int fd);
bool Write(int fd) const;
private:
- bool CheckPacketSize(size_t size, const char* name) const;
- bool CheckResult(int result, const char* operation_name) const;
- bool CheckHeaderLength(int result, const char* operation_name) const;
+ bool CheckHeaderLength(const char* name) const;
};
// FuseRequest represents file operation requests from /dev/fuse. It starts
diff --git a/libappfuse/tests/FuseBufferTest.cc b/libappfuse/tests/FuseBufferTest.cc
index c822135..db35d33 100644
--- a/libappfuse/tests/FuseBufferTest.cc
+++ b/libappfuse/tests/FuseBufferTest.cc
@@ -20,6 +20,8 @@
#include <string.h>
#include <sys/socket.h>
+#include <thread>
+
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
@@ -110,6 +112,30 @@
TestWriteInvalidLength(sizeof(fuse_in_header) - 1);
}
+TEST(FuseMessageTest, ShortWriteAndRead) {
+ int raw_fds[2];
+ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, raw_fds));
+
+ android::base::unique_fd fds[2];
+ fds[0].reset(raw_fds[0]);
+ fds[1].reset(raw_fds[1]);
+
+ const int send_buffer_size = 1024;
+ ASSERT_EQ(0, setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &send_buffer_size,
+ sizeof(int)));
+
+ bool succeed = false;
+ const int sender_fd = fds[0].get();
+ std::thread thread([sender_fd, &succeed] {
+ FuseRequest request;
+ request.header.len = 1024 * 4;
+ succeed = request.Write(sender_fd);
+ });
+ thread.detach();
+ FuseRequest request;
+ ASSERT_TRUE(request.Read(fds[1]));
+}
+
TEST(FuseResponseTest, Reset) {
FuseResponse response;
// Write 1 to the first ten bytes.
diff --git a/libcutils/multiuser.c b/libcutils/multiuser.c
index 0f4427b..0ef337d 100644
--- a/libcutils/multiuser.c
+++ b/libcutils/multiuser.c
@@ -15,21 +15,36 @@
*/
#include <cutils/multiuser.h>
+#include <private/android_filesystem_config.h>
userid_t multiuser_get_user_id(uid_t uid) {
- return uid / MULTIUSER_APP_PER_USER_RANGE;
+ return uid / AID_USER_OFFSET;
}
appid_t multiuser_get_app_id(uid_t uid) {
- return uid % MULTIUSER_APP_PER_USER_RANGE;
+ return uid % AID_USER_OFFSET;
}
-uid_t multiuser_get_uid(userid_t userId, appid_t appId) {
- return userId * MULTIUSER_APP_PER_USER_RANGE + (appId % MULTIUSER_APP_PER_USER_RANGE);
+uid_t multiuser_get_uid(userid_t user_id, appid_t app_id) {
+ return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET);
}
-appid_t multiuser_get_shared_app_gid(uid_t id) {
- return MULTIUSER_FIRST_SHARED_APPLICATION_GID + (id % MULTIUSER_APP_PER_USER_RANGE)
- - MULTIUSER_FIRST_APPLICATION_UID;
+gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id) {
+ if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
+ return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_CACHE_GID_START);
+ } else {
+ return -1;
+ }
+}
+gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id) {
+ if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
+ return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_SHARED_GID_START);
+ } else {
+ return -1;
+ }
+}
+
+gid_t multiuser_get_shared_app_gid(uid_t uid) {
+ return multiuser_get_shared_gid(multiuser_get_user_id(uid), multiuser_get_app_id(uid));
}
diff --git a/libcutils/tests/Android.bp b/libcutils/tests/Android.bp
index abe3c21..0b0dc09 100644
--- a/libcutils/tests/Android.bp
+++ b/libcutils/tests/Android.bp
@@ -26,7 +26,8 @@
"trace-dev_test.cpp",
"test_str_parms.cpp",
"android_get_control_socket_test.cpp",
- "android_get_control_file_test.cpp"
+ "android_get_control_file_test.cpp",
+ "multiuser_test.cpp"
],
},
diff --git a/libcutils/tests/multiuser_test.cpp b/libcutils/tests/multiuser_test.cpp
new file mode 100644
index 0000000..2307ea8
--- /dev/null
+++ b/libcutils/tests/multiuser_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <cutils/multiuser.h>
+#include <gtest/gtest.h>
+
+TEST(MultiuserTest, TestMerge) {
+ EXPECT_EQ(0, multiuser_get_uid(0, 0));
+ EXPECT_EQ(1000, multiuser_get_uid(0, 1000));
+ EXPECT_EQ(10000, multiuser_get_uid(0, 10000));
+ EXPECT_EQ(50000, multiuser_get_uid(0, 50000));
+ EXPECT_EQ(1000000, multiuser_get_uid(10, 0));
+ EXPECT_EQ(1001000, multiuser_get_uid(10, 1000));
+ EXPECT_EQ(1010000, multiuser_get_uid(10, 10000));
+ EXPECT_EQ(1050000, multiuser_get_uid(10, 50000));
+}
+
+TEST(MultiuserTest, TestSplitUser) {
+ EXPECT_EQ(0, multiuser_get_user_id(0));
+ EXPECT_EQ(0, multiuser_get_user_id(1000));
+ EXPECT_EQ(0, multiuser_get_user_id(10000));
+ EXPECT_EQ(0, multiuser_get_user_id(50000));
+ EXPECT_EQ(10, multiuser_get_user_id(1000000));
+ EXPECT_EQ(10, multiuser_get_user_id(1001000));
+ EXPECT_EQ(10, multiuser_get_user_id(1010000));
+ EXPECT_EQ(10, multiuser_get_user_id(1050000));
+}
+
+TEST(MultiuserTest, TestSplitApp) {
+ EXPECT_EQ(0, multiuser_get_app_id(0));
+ EXPECT_EQ(1000, multiuser_get_app_id(1000));
+ EXPECT_EQ(10000, multiuser_get_app_id(10000));
+ EXPECT_EQ(50000, multiuser_get_app_id(50000));
+ EXPECT_EQ(0, multiuser_get_app_id(1000000));
+ EXPECT_EQ(1000, multiuser_get_app_id(1001000));
+ EXPECT_EQ(10000, multiuser_get_app_id(1010000));
+ EXPECT_EQ(50000, multiuser_get_app_id(1050000));
+}
+
+TEST(MultiuserTest, TestCache) {
+ EXPECT_EQ(-1, multiuser_get_cache_gid(0, 0));
+ EXPECT_EQ(-1, multiuser_get_cache_gid(0, 1000));
+ EXPECT_EQ(20000, multiuser_get_cache_gid(0, 10000));
+ EXPECT_EQ(-1, multiuser_get_cache_gid(0, 50000));
+ EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000));
+}
+
+TEST(MultiuserTest, TestShared) {
+ EXPECT_EQ(-1, multiuser_get_shared_gid(0, 0));
+ EXPECT_EQ(-1, multiuser_get_shared_gid(0, 1000));
+ EXPECT_EQ(50000, multiuser_get_shared_gid(0, 10000));
+ EXPECT_EQ(-1, multiuser_get_shared_gid(0, 50000));
+ EXPECT_EQ(1050000, multiuser_get_shared_gid(10, 10000));
+}
diff --git a/libcutils/uevent.c b/libcutils/uevent.c
index de5d227..f548dca 100644
--- a/libcutils/uevent.c
+++ b/libcutils/uevent.c
@@ -116,7 +116,12 @@
if(s < 0)
return -1;
- setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &buf_sz, sizeof(buf_sz));
+ /* buf_sz should be less than net.core.rmem_max for this to succeed */
+ if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buf_sz, sizeof(buf_sz)) < 0) {
+ close(s);
+ return -1;
+ }
+
setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index bab87ba..3c8bd75 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -182,7 +182,7 @@
}
// Parse /data/system/packages.list
- uid_t userId = uid % AID_USER;
+ uid_t userId = uid % AID_USER_OFFSET;
const char *name = android::uidToName(userId);
if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 8903255..249b9e2 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -125,6 +125,12 @@
write /proc/sys/kernel/sched_rt_runtime_us 950000
write /proc/sys/kernel/sched_rt_period_us 1000000
+ # Assign reasonable ceiling values for socket rcv/snd buffers.
+ # These should almost always be overridden by the target per the
+ # the corresponding technology maximums.
+ write /proc/sys/net/core/rmem_max 262144
+ write /proc/sys/net/core/wmem_max 262144
+
# reflect fwmark from incoming packets onto generated replies
write /proc/sys/net/ipv4/fwmark_reflect 1
write /proc/sys/net/ipv6/fwmark_reflect 1
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp
index aec51f4..e7b8cc2 100644
--- a/run-as/run-as.cpp
+++ b/run-as/run-as.cpp
@@ -165,12 +165,12 @@
if (setegid(old_egid) == -1) error(1, errno, "couldn't restore egid");
// Verify that user id is not too big.
- if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) {
+ if ((UID_MAX - info.uid) / AID_USER_OFFSET < (uid_t)userId) {
error(1, 0, "user id too big: %d", userId);
}
// Calculate user app ID.
- uid_t userAppId = (AID_USER * userId) + info.uid;
+ uid_t userAppId = (AID_USER_OFFSET * userId) + info.uid;
// Reject system packages.
if (userAppId < AID_APP) {