Merge "libutils: Looper add 'repoll'" into main
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index c416f4d..a5da6e3 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -531,11 +531,16 @@
     // If there is no intermediate device-mapper node, then partitions cannot be
     // opened writable due to sepolicy and exclusivity of having a mounted
     // filesystem. This should only happen on devices with no encryption, or
-    // devices with FBE and no metadata encryption. For these cases it suffices
-    // to perform normal file writes to /data/gsi (which is unencrypted).
+    // devices with FBE and no metadata encryption. For these cases we COULD
+    // perform normal writes to /data/gsi (which is unencrypted), but given that
+    // metadata encryption has been mandated since Android R, we don't actually
+    // support or test this.
     //
-    // Note: this is not gated on DeviceInfo, because the recovery-specific path
-    // must only be used in actual recovery.
+    // So, we validate here that /data is backed by device-mapper. This code
+    // isn't needed in recovery since there is no /data.
+    //
+    // If this logic sticks for a release, we can remove MapWithLoopDevice, as
+    // well as WrapUserdataIfNeeded in fs_mgr.
     std::string block_device;
     bool can_use_devicemapper;
     if (!FiemapWriter::GetBlockDeviceForFile(image_header, &block_device, &can_use_devicemapper)) {
@@ -543,21 +548,16 @@
         return false;
     }
 
-    if (can_use_devicemapper) {
-        if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
-            return false;
-        }
-    } else if (!MapWithLoopDevice(name, timeout_ms, path)) {
-        return false;
-    }
-#else
-    // In recovery, we can *only* use device-mapper, since partitions aren't
-    // mounted. That also means we cannot call GetBlockDeviceForFile.
-    if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
+    if (!can_use_devicemapper) {
+        LOG(ERROR) << "Cannot map image: /data must be mounted on top of device-mapper.";
         return false;
     }
 #endif
 
+    if (!MapWithDmLinear(*partition_opener_.get(), name, timeout_ms, path)) {
+        return false;
+    }
+
     // Set a property so we remember this is mapped.
     auto prop_name = GetStatusPropertyName(name);
     if (!android::base::SetProperty(prop_name, *path)) {
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 1e035bb..8c6e548 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -141,6 +141,7 @@
 #define AID_SDK_SANDBOX 1090      /* SDK sandbox virtual UID */
 #define AID_SECURITY_LOG_WRITER 1091 /* write to security log */
 #define AID_PRNG_SEEDER 1092         /* PRNG seeder daemon */
+#define AID_UPROBESTATS 1093         /* uid for uprobestats */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a8e867d..768e0ff 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -109,6 +109,9 @@
     symlink /proc/self/fd/1 /dev/stdout
     symlink /proc/self/fd/2 /dev/stderr
 
+    # Create socket dir for ot-daemon
+    mkdir /dev/socket/ot-daemon 0770 thread_network thread_network
+
     # Create energy-aware scheduler tuning nodes
     mkdir /dev/stune/foreground
     mkdir /dev/stune/background
@@ -813,6 +816,7 @@
     mkdir /data/misc/apexdata 0711 root root
     mkdir /data/misc/apexrollback 0700 root root
     mkdir /data/misc/appcompat/ 0700 system system
+    mkdir /data/misc/uprobestats-configs/ 0777 uprobestats uprobestats
     mkdir /data/misc/snapshotctl_log 0755 root root
     # create location to store pre-reboot information
     mkdir /data/misc/prereboot 0700 system system
diff --git a/trusty/secretkeeper/Android.bp b/trusty/secretkeeper/Android.bp
new file mode 100644
index 0000000..f6b740a
--- /dev/null
+++ b/trusty/secretkeeper/Android.bp
@@ -0,0 +1,96 @@
+//
+// Copyright (C) 2022 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_binary {
+    name: "android.hardware.security.secretkeeper.trusty",
+    relative_install_path: "hw",
+    vendor: true,
+    init_rc: ["android.hardware.security.secretkeeper.trusty.rc"],
+    vintf_fragments: ["android.hardware.security.secretkeeper.trusty.xml"],
+    srcs: [
+        "src/hal_main.rs",
+    ],
+    rustlibs: [
+        "libandroid_logger",
+        "libbinder_rs",
+        "libauthgraph_hal",
+        "libtrusty-rs",
+        "liblibc",
+        "liblog_rust",
+        "libsecretkeeper_hal",
+    ],
+    defaults: [
+        "secretkeeper_use_latest_hal_aidl_rust",
+    ],
+    prefer_rlib: true,
+}
+
+cc_defaults {
+    name: "trusty_secretkeeper_fuzz_defaults",
+    srcs: [":trusty_tipc_fuzzer"],
+    fuzz_config: {
+        cc: [
+            "alanstokes@google.com",
+            "drysdale@google.com",
+            "shikhapanwar@google.com",
+        ],
+        componentid: 867125,
+        // TODO: add Secretkeeper hotlist
+        // hotlists: [""],
+    },
+}
+
+cc_fuzz {
+    name: "trusty_secretkeeper_sk_fuzzer",
+    defaults: [
+        "trusty_fuzzer_defaults",
+        "trusty_secretkeeper_fuzz_defaults",
+    ],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.secretkeeper\"",
+        "-DTRUSTY_APP_UUID=\"4582bf12-1f7d-4830-9be5-36e6bd91c2c6\"",
+        "-DTRUSTY_APP_FILENAME=\"secretkeeper_app.syms.elf\"",
+    ],
+}
+
+cc_fuzz {
+    name: "trusty_secretkeeper_ag_fuzzer",
+    defaults: [
+        "trusty_fuzzer_defaults",
+        "trusty_secretkeeper_fuzz_defaults",
+    ],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.secretkeeper.authgraph\"",
+        "-DTRUSTY_APP_UUID=\"4582bf12-1f7d-4830-9be5-36e6bd91c2c6\"",
+        "-DTRUSTY_APP_FILENAME=\"secretkeeper_app.syms.elf\"",
+    ],
+}
+
+cc_fuzz {
+    name: "trusty_secretkeeper_bl_fuzzer",
+    defaults: [
+        "trusty_fuzzer_defaults",
+        "trusty_secretkeeper_fuzz_defaults",
+    ],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.secretkeeper.bootloader\"",
+        "-DTRUSTY_APP_UUID=\"4582bf12-1f7d-4830-9be5-36e6bd91c2c6\"",
+        "-DTRUSTY_APP_FILENAME=\"secretkeeper_app.syms.elf\"",
+    ],
+}
diff --git a/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc
new file mode 100644
index 0000000..3be03ad
--- /dev/null
+++ b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.rc
@@ -0,0 +1,4 @@
+service vendor.secretkeeper.trusty /vendor/bin/hw/android.hardware.security.secretkeeper.trusty
+    class hal
+    user nobody
+    group drmrpc
\ No newline at end of file
diff --git a/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml
new file mode 100644
index 0000000..2ac152b
--- /dev/null
+++ b/trusty/secretkeeper/android.hardware.security.secretkeeper.trusty.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.security.secretkeeper</name>
+        <version>1</version>
+        <fqname>ISecretkeeper/default</fqname>
+    </hal>
+</manifest>
diff --git a/trusty/secretkeeper/src/hal_main.rs b/trusty/secretkeeper/src/hal_main.rs
new file mode 100644
index 0000000..9439c36
--- /dev/null
+++ b/trusty/secretkeeper/src/hal_main.rs
@@ -0,0 +1,141 @@
+//
+// Copyright (C) 2022 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.
+
+//! This module implements the HAL service for Secretkeeper in Trusty.
+use authgraph_hal::{channel::SerializedChannel};
+use secretkeeper_hal::SecretkeeperService;
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
+    ISecretkeeper, BpSecretkeeper,
+};
+use log::{error, info};
+use std::{
+    ffi::CString,
+    panic,
+    sync::{Arc, Mutex},
+};
+use trusty::DEFAULT_DEVICE;
+
+const SK_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper";
+const AG_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper.authgraph";
+
+static SERVICE_INSTANCE: &str = "default";
+
+/// Local error type for failures in the HAL service.
+#[derive(Debug, Clone)]
+struct HalServiceError(String);
+
+#[derive(Debug)]
+struct TipcChannel {
+    channel: Arc<Mutex<trusty::TipcChannel>>,
+}
+
+impl TipcChannel {
+    fn new(channel: trusty::TipcChannel) -> Self {
+        Self { channel: Arc::new(Mutex::new(channel)) }
+    }
+}
+
+impl SerializedChannel for TipcChannel {
+    const MAX_SIZE: usize = 4000;
+    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+        // Hold lock across both request and response.
+        let mut channel = self.channel.lock().unwrap();
+        channel.send(req_data).map_err(|e| {
+            binder::Status::new_exception(
+                binder::ExceptionCode::TRANSACTION_FAILED,
+                Some(
+                    &CString::new(format!(
+                        "Failed to send the request via tipc channel because of {:?}",
+                        e
+                    ))
+                    .unwrap(),
+                ),
+            )
+        })?;
+        // TODO: cope with fragmentation and reassembly
+        let mut rsp_data = Vec::new();
+        channel.recv(&mut rsp_data).map_err(|e| {
+            binder::Status::new_exception(
+                binder::ExceptionCode::TRANSACTION_FAILED,
+                Some(
+                    &CString::new(format!(
+                        "Failed to receive the response via tipc channel because of {:?}",
+                        e
+                    ))
+                    .unwrap(),
+                ),
+            )
+        })?;
+        Ok(rsp_data)
+    }
+}
+
+fn main() {
+    if let Err(e) = inner_main() {
+        panic!("HAL service failed: {:?}", e);
+    }
+}
+
+fn inner_main() -> Result<(), HalServiceError> {
+    // Initialize Android logging.
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("secretkeeper-hal-trusty")
+            .with_min_level(log::Level::Info)
+            .with_log_id(android_logger::LogId::System),
+    );
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        error!("{}", panic_info);
+    }));
+
+    info!("Trusty Secretkeeper HAL service is starting.");
+
+    info!("Starting thread pool now.");
+    binder::ProcessState::start_thread_pool();
+
+    // Create connections to the TA.
+    let ag_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, AG_TIPC_SERVICE_PORT)
+        .map_err(|e| {
+            HalServiceError(format!(
+                "Failed to connect to Trusty port {AG_TIPC_SERVICE_PORT} because of {:?}.",
+                e
+            ))
+        })?;
+    let ag_tipc_channel = TipcChannel::new(ag_connection);
+
+    let sk_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, SK_TIPC_SERVICE_PORT)
+        .map_err(|e| {
+            HalServiceError(format!(
+                "Failed to connect to Trusty port {SK_TIPC_SERVICE_PORT} because of {:?}.",
+                e
+            ))
+        })?;
+    let sk_tipc_channel = TipcChannel::new(sk_connection);
+
+    // Register the AIDL service
+    let service = SecretkeeperService::new_as_binder(sk_tipc_channel, ag_tipc_channel);
+    let service_name =
+        format!("{}/{}", <BpSecretkeeper as ISecretkeeper>::get_descriptor(), SERVICE_INSTANCE);
+    binder::add_service(&service_name, service.as_binder()).map_err(|e| {
+        HalServiceError(format!("Failed to register service {} because of {:?}.", service_name, e))
+    })?;
+
+    info!("Successfully registered Secretkeeper HAL service.");
+    info!("Joining thread pool now.");
+    binder::ProcessState::join_thread_pool();
+    info!("Secretkeeper HAL service is terminating."); // should not reach here
+    Ok(())
+}
diff --git a/trusty/trusty-base.mk b/trusty/trusty-base.mk
index 1986c73..d645c3e 100644
--- a/trusty/trusty-base.mk
+++ b/trusty/trusty-base.mk
@@ -35,8 +35,16 @@
     LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.trusty
 endif
 
+# TODO(b/306364873): move this to be flag-controlled?
+ifeq ($(SECRETKEEPER_ENABLED),)
+    LOCAL_SECRETKEEPER_PRODUCT_PACKAGE :=
+else
+    LOCAL_SECRETKEEPER_PRODUCT_PACKAGE := android.hardware.security.secretkeeper.trusty
+endif
+
 PRODUCT_PACKAGES += \
 	$(LOCAL_KEYMINT_PRODUCT_PACKAGE) \
+	$(LOCAL_SECRETKEEPER_PRODUCT_PACKAGE) \
 	android.hardware.gatekeeper-service.trusty \
 	trusty_apploader \