Expose binder security context to rust binder services

This patch exposes AIBinder_setRequestingSid and AIBinder_getCallingSid
to binder services written in Rust. This is required by services to
effectively enforce SEPolicy because relying only on the caller's PID is
racy.

Bug: 165070170
Test: atest rustBinderTest
Change-Id: Iae25d4fedded7d133354ba4c82527f33e5d5e1ce
diff --git a/libs/binder/rust/src/state.rs b/libs/binder/rust/src/state.rs
index 992f074..0e05f10 100644
--- a/libs/binder/rust/src/state.rs
+++ b/libs/binder/rust/src/state.rs
@@ -98,4 +98,36 @@
             sys::AIBinder_getCallingPid()
         }
     }
+
+    /// This function makes the client's security context available to the
+    /// service calling this function. This can be used for access control.
+    /// It does not suffer from the TOCTOU issues of get_calling_pid.
+    ///
+    /// Implementations of `check_permission` should use the given CStr
+    /// argument as context for selinux permission checks. If `None` is
+    /// given, the implementation should fall back to using the PID
+    /// instead.
+    ///
+    /// Note: `None` may be passed to the callback if the caller did not
+    /// `set_requesting_sid` on the serviced binder, or if the underlying
+    /// kernel is too old to support this feature.
+    pub fn with_calling_sid<T, F>(check_permission: F) -> T
+    where
+        for<'a> F: FnOnce(Option<&'a std::ffi::CStr>) -> T {
+        // Safety: AIBinder_getCallingSid returns a c-string pointer
+        // that is valid for a transaction. Also, the string returned
+        // is thread local. By restricting the lifetime of the CStr
+        // reference to the scope of the callback, we prevent it being
+        // used beyond the guaranteed lifetime.
+        check_permission(unsafe {
+            let sid = sys::AIBinder_getCallingSid();
+            // AIBinder_getCallingSid() returns a '\0' terminated string
+            // or NULL.
+            if sid.is_null() {
+                None
+            } else {
+                Some(std::ffi::CStr::from_ptr(sid))
+            }
+        })
+    }
 }