Merge "fs_mgr: Revert "Try to recover corrupted ext4 /data with backup superblock""
diff --git a/adb/Android.bp b/adb/Android.bp
index 87ac54d..8addf95 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -117,6 +117,7 @@
     static_libs: [
         "libadb_crypto",
         "libadb_pairing_connection",
+        "libadb_sysdeps",
         "libadb_tls_connection",
         "libadbd",
         "libadbd_core",
@@ -167,6 +168,7 @@
     "services.cpp",
     "sockets.cpp",
     "socket_spec.cpp",
+    "sysdeps/env.cpp",
     "sysdeps/errno.cpp",
     "transport.cpp",
     "transport_fd.cpp",
@@ -261,6 +263,43 @@
     ],
 }
 
+cc_library {
+    name: "libadb_sysdeps",
+    defaults: ["adb_defaults"],
+    recovery_available: true,
+    host_supported: true,
+    compile_multilib: "both",
+    min_sdk_version: "apex_inherit",
+
+    srcs: [
+        "sysdeps/env.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+
+    target: {
+        windows: {
+            enabled: true,
+            ldflags: ["-municode"],
+        },
+    },
+
+    export_include_dirs: ["."],
+
+    visibility: [
+        "//system/core/adb:__subpackages__",
+        "//bootable/recovery/minadbd:__subpackages__",
+    ],
+
+    apex_available: [
+        "com.android.adbd",
+        "test_com.android.adbd",
+    ],
+}
+
 cc_test_host {
     name: "adb_test",
     defaults: ["adb_defaults"],
@@ -274,6 +313,7 @@
         "libadb_pairing_auth_static",
         "libadb_pairing_connection_static",
         "libadb_protos_static",
+        "libadb_sysdeps",
         "libadb_tls_connection_static",
         "libbase",
         "libcutils",
@@ -330,6 +370,7 @@
         "libadb_pairing_auth",
         "libadb_pairing_connection",
         "libadb_protos",
+        "libadb_sysdeps",
         "libadb_tls_connection",
         "libandroidfw",
         "libapp_processes_protos_full",
@@ -831,6 +872,7 @@
         "libadb_pairing_auth_static",
         "libadb_pairing_connection_static",
         "libadb_protos_static",
+        "libadb_sysdeps",
         "libadb_tls_connection_static",
         "libandroidfw",
         "libbase",
diff --git a/adb/crypto/Android.bp b/adb/crypto/Android.bp
index 9d14b03..e2c27f1 100644
--- a/adb/crypto/Android.bp
+++ b/adb/crypto/Android.bp
@@ -48,6 +48,7 @@
 
     shared_libs: [
         "libadb_protos",
+        "libadb_sysdeps",
         "libbase",
         "liblog",
         "libcrypto",
@@ -76,5 +77,6 @@
 
     static_libs: [
         "libadb_protos_static",
+        "libadb_sysdeps",
     ],
 }
diff --git a/adb/crypto/rsa_2048_key.cpp b/adb/crypto/rsa_2048_key.cpp
index 7911af9..6d9ee30 100644
--- a/adb/crypto/rsa_2048_key.cpp
+++ b/adb/crypto/rsa_2048_key.cpp
@@ -20,32 +20,11 @@
 #include <crypto_utils/android_pubkey.h>
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
+#include <sysdeps/env.h>
 
 namespace adb {
 namespace crypto {
 
-namespace {
-std::string get_user_info() {
-    std::string hostname;
-    if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
-#if !defined(_WIN32)
-    char buf[64];
-    if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
-#endif
-    if (hostname.empty()) hostname = "unknown";
-
-    std::string username;
-    if (getenv("LOGNAME")) username = getenv("LOGNAME");
-#if !defined(_WIN32)
-    if (username.empty() && getlogin()) username = getlogin();
-#endif
-    if (username.empty()) hostname = "unknown";
-
-    return " " + username + "@" + hostname;
-}
-
-}  // namespace
-
 bool CalculatePublicKey(std::string* out, RSA* private_key) {
     uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
     if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
@@ -63,7 +42,10 @@
     size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
                                            sizeof(binary_key_data));
     out->resize(actual_length);
-    out->append(get_user_info());
+    out->append(" ");
+    out->append(sysdeps::GetLoginNameUTF8());
+    out->append("@");
+    out->append(sysdeps::GetHostNameUTF8());
     return true;
 }
 
diff --git a/adb/crypto/tests/Android.bp b/adb/crypto/tests/Android.bp
index b32dcf7..b041055 100644
--- a/adb/crypto/tests/Android.bp
+++ b/adb/crypto/tests/Android.bp
@@ -35,6 +35,7 @@
     static_libs: [
         "libadb_crypto_static",
         "libadb_protos_static",
+        "libadb_sysdeps",
     ],
 
     test_suites: ["device-tests"],
diff --git a/adb/sysdeps/env.cpp b/adb/sysdeps/env.cpp
new file mode 100644
index 0000000..4058728
--- /dev/null
+++ b/adb/sysdeps/env.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 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 "sysdeps/env.h"
+
+#ifdef _WIN32
+#include <lmcons.h>
+#include <windows.h>
+#endif  // _WIN32
+
+#include <android-base/utf8.h>
+
+namespace adb {
+namespace sysdeps {
+
+std::optional<std::string> GetEnvironmentVariable(std::string_view var) {
+    if (var.empty()) {
+        return std::nullopt;
+    }
+
+#ifdef _WIN32
+    constexpr size_t kMaxEnvVarSize = 32767;
+    wchar_t wbuf[kMaxEnvVarSize];
+    std::wstring wvar;
+    if (!android::base::UTF8ToWide(var.data(), &wvar)) {
+        return std::nullopt;
+    }
+
+    auto sz = ::GetEnvironmentVariableW(wvar.data(), wbuf, sizeof(wbuf));
+    if (sz == 0) {
+        return std::nullopt;
+    }
+
+    std::string val;
+    if (!android::base::WideToUTF8(wbuf, &val)) {
+        return std::nullopt;
+    }
+
+    return std::make_optional(val);
+#else  // !_WIN32
+    const char* val = getenv(var.data());
+    if (val == nullptr) {
+        return std::nullopt;
+    }
+
+    return std::make_optional(std::string(val));
+#endif
+}
+
+#ifdef _WIN32
+constexpr char kHostNameEnvVar[] = "COMPUTERNAME";
+constexpr char kUserNameEnvVar[] = "USERNAME";
+#else
+constexpr char kHostNameEnvVar[] = "HOSTNAME";
+constexpr char kUserNameEnvVar[] = "LOGNAME";
+#endif
+
+std::string GetHostNameUTF8() {
+    const auto hostName = GetEnvironmentVariable(kHostNameEnvVar);
+    if (hostName && !hostName->empty()) {
+        return *hostName;
+    }
+
+#ifdef _WIN32
+    wchar_t wbuf[MAX_COMPUTERNAME_LENGTH + 1];
+    DWORD size = sizeof(wbuf);
+    if (!GetComputerNameW(wbuf, &size) || size == 0) {
+        return "";
+    }
+
+    std::string name;
+    if (!android::base::WideToUTF8(wbuf, &name)) {
+        return "";
+    }
+
+    return name;
+#else   // !_WIN32
+    char buf[256];
+    return (gethostname(buf, sizeof(buf)) == -1) ? "" : buf;
+#endif  // _WIN32
+}
+
+std::string GetLoginNameUTF8() {
+    const auto userName = GetEnvironmentVariable(kUserNameEnvVar);
+    if (userName && !userName->empty()) {
+        return *userName;
+    }
+
+#ifdef _WIN32
+    wchar_t wbuf[UNLEN + 1];
+    DWORD size = sizeof(wbuf);
+    if (!GetUserNameW(wbuf, &size) || size == 0) {
+        return "";
+    }
+
+    std::string login;
+    if (!android::base::WideToUTF8(wbuf, &login)) {
+        return "";
+    }
+
+    return login;
+#else   // !_WIN32
+    const char* login = getlogin();
+    return login ? login : "";
+#endif  // _WIN32
+}
+
+}  // namespace sysdeps
+}  // namespace adb
diff --git a/adb/sysdeps/env.h b/adb/sysdeps/env.h
new file mode 100644
index 0000000..b39b675
--- /dev/null
+++ b/adb/sysdeps/env.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+
+namespace adb {
+namespace sysdeps {
+
+// Attempts to retrieve the environment variable value for |var|. Returns std::nullopt
+// if unset.
+std::optional<std::string> GetEnvironmentVariableUTF8(std::string_view var);
+
+// Gets the host name of the system. Returns empty string on failure.
+std::string GetHostNameUTF8();
+// Gets the current login user. Returns empty string on failure.
+std::string GetLoginNameUTF8();
+
+}  // namespace sysdeps
+}  // namespace adb
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index be82bc0..217a6b7 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -1010,55 +1010,6 @@
     return _fh_to_int(f);
 }
 
-static bool isBlankStr(const char* str) {
-    for (; *str != '\0'; ++str) {
-        if (!isblank(*str)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-int adb_gethostname(char* name, size_t len) {
-    const char* computerName = adb_getenv("COMPUTERNAME");
-    if (computerName && !isBlankStr(computerName)) {
-        strncpy(name, computerName, len);
-        name[len - 1] = '\0';
-        return 0;
-    }
-
-    wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
-    DWORD size = sizeof(buffer);
-    if (!GetComputerNameW(buffer, &size)) {
-        return -1;
-    }
-    std::string name_utf8;
-    if (!android::base::WideToUTF8(buffer, &name_utf8)) {
-        return -1;
-    }
-
-    strncpy(name, name_utf8.c_str(), len);
-    name[len - 1] = '\0';
-    return 0;
-}
-
-int adb_getlogin_r(char* buf, size_t bufsize) {
-    wchar_t buffer[UNLEN + 1];
-    DWORD len = sizeof(buffer);
-    if (!GetUserNameW(buffer, &len)) {
-        return -1;
-    }
-
-    std::string login;
-    if (!android::base::WideToUTF8(buffer, &login)) {
-        return -1;
-    }
-
-    strncpy(buf, login.c_str(), bufsize);
-    buf[bufsize - 1] = '\0';
-    return 0;
-}
-
 #undef accept
 int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen) {
     FH serverfh = _fh_from_int(serverfd, __func__);
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index 82ed6b2..7123f60 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -41,7 +41,7 @@
 
 // Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
 // O_CLOEXEC is always set.
-static int socket_local_client(const std::string& name, int type) {
+static int socket_local_client(const std::string& name, int type, bool timeout) {
   sockaddr_un addr = {.sun_family = AF_LOCAL};
 
   std::string path = "/dev/socket/" + name;
@@ -55,6 +55,18 @@
     return -1;
   }
 
+  if (timeout) {
+    // Sending and receiving messages should be instantaneous, but we don't want to wait forever if
+    // logd is hung, so we set a gracious 2s timeout.
+    struct timeval t = {2, 0};
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) == -1) {
+      return -1;
+    }
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {
+      return -1;
+    }
+  }
+
   if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
     close(fd);
     return -1;
@@ -69,7 +81,7 @@
   size_t len;
   char* cp;
   int errno_save = 0;
-  int sock = socket_local_client("logd", SOCK_STREAM);
+  int sock = socket_local_client("logd", SOCK_STREAM, true);
   if (sock < 0) {
     return sock;
   }
@@ -268,7 +280,7 @@
     return sock;
   }
 
-  sock = socket_local_client("logdr", SOCK_SEQPACKET);
+  sock = socket_local_client("logdr", SOCK_SEQPACKET, false);
   if (sock <= 0) {
     if ((sock == -1) && errno) {
       return -errno;
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index bbdd317..ceabf62 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -336,7 +336,6 @@
     }
 
     ParseKernelCmdlineOptions();
-    android::base::SetMinimumLogSeverity(android::base::INFO);
 }
 
 void Modprobe::EnableBlocklist(bool enable) {
diff --git a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
index 94f5a73..0415ef6 100644
--- a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
+++ b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
@@ -16,6 +16,11 @@
 
 #include "UnwinderComponentCreator.h"
 
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
 std::unique_ptr<Regs> GetRegisters(ArchEnum arch) {
   switch (arch) {
     case unwindstack::ARCH_ARM: {
@@ -109,13 +114,28 @@
   return elf;
 }
 
+static constexpr size_t kPageSize = 4096;
+
+static constexpr uint64_t AlignToPage(uint64_t address) {
+  return (address + kPageSize - 1) & ~(kPageSize - 1);
+}
+
 std::unique_ptr<Maps> GetMaps(FuzzedDataProvider* data_provider) {
   std::unique_ptr<Maps> maps = std::make_unique<Maps>();
+  std::map<uint64_t, uint64_t> map_ends;
   uint8_t entry_count = data_provider->ConsumeIntegralInRange<uint8_t>(0, kMaxMapEntryCount);
   for (uint8_t i = 0; i < entry_count; i++) {
-    uint64_t start = data_provider->ConsumeIntegral<uint64_t>();
-    uint64_t end = data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX);
-    uint64_t offset = data_provider->ConsumeIntegral<uint64_t>();
+    uint64_t start = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
+    uint64_t end = AlignToPage(data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX));
+    // Make sure not to add overlapping maps, that is not something that can
+    // happen in the real world.
+    auto entry = map_ends.upper_bound(start);
+    if (entry != map_ends.end() && end > entry->second) {
+      continue;
+    }
+    map_ends[end] = start;
+
+    uint64_t offset = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
     std::string map_info_name = data_provider->ConsumeRandomLengthString(kMaxMapInfoNameLen);
     uint8_t flags = PROT_READ | PROT_WRITE;