Drop inheritable caps and caps bounding set before executing payload

This change basically does the following things:

* Add rust_bindgen for the libcap.
* Add libcap_rust wrapping the bindgen and providing
  drop_inhertiable_caps and drop_bounding_set APIs;
* Call the libcap_rust APIs before execve'ing into the payload binary.
  This is done using the CommandExt::pre_exec function.

Additionally this change adds basic tests for libcap_rust library and
the e2e test to verify that binary running payload have zero
capabilities.

Bug: 243633980
Test: atest libcap_rust.test
Test: atest MicrodroidTestApp
Test: adb shell /apex/com.android.virt/bin/vm run-microdroid
Test: enter microdroid shell & check microdroid_launcher has empty caps
Change-Id: Ibfb45ec912df0ad0a1db62b24c22fbe5a61ff5f3
diff --git a/microdroid_manager/Android.bp b/microdroid_manager/Android.bp
index 44b4c01..383f371 100644
--- a/microdroid_manager/Android.bp
+++ b/microdroid_manager/Android.bp
@@ -18,6 +18,7 @@
         "libapkverify",
         "libbinder_rs",
         "libbyteorder",
+        "libcap_rust",
         "libdiced",
         "libdiced_open_dice_cbor",
         "libdiced_sample_inputs",
diff --git a/microdroid_manager/microdroid_manager.rc b/microdroid_manager/microdroid_manager.rc
index c41ee38..97d14b5 100644
--- a/microdroid_manager/microdroid_manager.rc
+++ b/microdroid_manager/microdroid_manager.rc
@@ -7,6 +7,8 @@
     setenv RUST_LOG info
     # TODO(jooyung) remove this when microdroid_manager becomes a daemon
     oneshot
-    # SYS_BOOT is required to exec kexecload from microdroid_manager
-    capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT
+    # CAP_SYS_BOOT is required to exec kexecload from microdroid_manager
+    # CAP_SETCAP is required to allow microdroid_manager to drop capabilities
+    #   before executing the payload
+    capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT SETPCAP
     socket vm_payload_service stream 0666 system system
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 6a37b88..b081aac 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -55,6 +55,7 @@
 use std::env;
 use std::fs::{self, create_dir, OpenOptions};
 use std::io::Write;
+use std::os::unix::process::CommandExt;
 use std::os::unix::process::ExitStatusExt;
 use std::path::Path;
 use std::process::{Child, Command, Stdio};
@@ -795,6 +796,24 @@
             command
         }
     };
+
+    unsafe {
+        // SAFETY: we are not accessing any resource of the parent process.
+        command.pre_exec(|| {
+            info!("dropping capabilities before executing payload");
+            // It is OK to continue with payload execution even if the calls below fail, since
+            // whether process can use a capability is controlled by the SELinux. Dropping the
+            // capabilities here is just another defense-in-depth layer.
+            if let Err(e) = cap::drop_inheritable_caps() {
+                error!("failed to drop inheritable capabilities: {:?}", e);
+            }
+            if let Err(e) = cap::drop_bounding_set() {
+                error!("failed to drop bounding set: {:?}", e);
+            }
+            Ok(())
+        });
+    }
+
     command.stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null());
 
     info!("notifying payload started");