From 6fb8b256c18b47bf9443db7ee02d25d92d404f8e Mon Sep 17 00:00:00 2001 From: Victor Hsieh Date: Fri, 3 Dec 2021 16:30:04 -0800 Subject: [PATCH] composd: prepare staging directory w/ libartpalette-system Output files are staged until they are fully generated, then move to the final location. The staging directory has a different SELinux context to prevent misuse, and should change when it's moved to the final directory. This change makes composd to follow the same setup, using libartpalette. As a result, the output are no longer stored in CompOS's own apexdata (which was not intentional). This change does not use bindgen, which seems have some difficulty to bridge `const char**` correctly. Neither cxx, since it doesn't seem to simplify the (already simple) call. Bug: 205750213 Test: See odrefresh produces output in the staging directory Change-Id: Ifc97b31a98052a31209556449d1642089a8c0e2e --- compos/composd/native/Android.bp | 7 +++++- compos/composd/native/lib.rs | 42 +++++++++++++++++++++++++++++--- compos/composd/src/service.rs | 15 +++--------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/compos/composd/native/Android.bp b/compos/composd/native/Android.bp index ad0afd9c..135f4d46 100644 --- a/compos/composd/native/Android.bp +++ b/compos/composd/native/Android.bp @@ -7,12 +7,17 @@ rust_library { crate_name: "composd_native", srcs: ["lib.rs"], rustlibs: [ + "libanyhow", "libcxx", + "liblibc", ], static_libs: [ "libcomposd_native_cpp", ], - shared_libs: ["libcrypto"], + shared_libs: [ + "libartpalette-system", + "libcrypto", + ], apex_available: ["com.android.compos"], } diff --git a/compos/composd/native/lib.rs b/compos/composd/native/lib.rs index ace9600b..cbec7fdd 100644 --- a/compos/composd/native/lib.rs +++ b/compos/composd/native/lib.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Bindings native helpers for composd. +//! Native helpers for composd. -pub use ffi::*; +pub use art::*; +pub use crypto::*; #[cxx::bridge] -mod ffi { +mod crypto { /// Contains either a key or a reason why the key could not be extracted. struct KeyResult { /// The extracted key. If empty, the attempt to extract the key failed. @@ -36,3 +37,38 @@ mod ffi { fn extract_rsa_public_key(der_certificate: &[u8]) -> KeyResult; } } + +mod art { + use anyhow::{anyhow, Result}; + use libc::c_char; + use std::ffi::{CStr, OsStr}; + use std::io::Error; + use std::os::unix::ffi::OsStrExt; + use std::path::Path; + use std::ptr::null; + + // From libartpalette(-system) + extern "C" { + fn PaletteCreateOdrefreshStagingDirectory(out_staging_dir: *mut *const c_char) -> i32; + } + const PALETTE_STATUS_OK: i32 = 0; + const PALETTE_STATUS_CHECK_ERRNO: i32 = 1; + + /// Creates and returns the staging directory for odrefresh. + pub fn palette_create_odrefresh_staging_directory() -> Result<&'static Path> { + let mut staging_dir: *const c_char = null(); + // SAFETY: The C function always returns a non-null C string (after created the directory). + let status = unsafe { PaletteCreateOdrefreshStagingDirectory(&mut staging_dir) }; + match status { + PALETTE_STATUS_OK => { + // SAFETY: The previously returned `*const c_char` should point to a legitimate C + // string. + let cstr = unsafe { CStr::from_ptr(staging_dir) }; + let path = OsStr::from_bytes(cstr.to_bytes()).as_ref(); + Ok(path) + } + PALETTE_STATUS_CHECK_ERRNO => Err(anyhow!(Error::last_os_error().to_string())), + _ => Err(anyhow!("Failed with palette status {}", status)), + } + } +} diff --git a/compos/composd/src/service.rs b/compos/composd/src/service.rs index b1267101..a2898a2b 100644 --- a/compos/composd/src/service.rs +++ b/compos/composd/src/service.rs @@ -20,7 +20,6 @@ use crate::compilation_task::CompilationTask; use crate::fd_server_helper::FdServerConfig; use crate::instance_manager::InstanceManager; -use crate::instance_starter::CompOsInstance; use crate::util::to_binder_result; use android_system_composd::aidl::android::system::composd::{ ICompilationTask::{BnCompilationTask, ICompilationTask}, @@ -31,12 +30,11 @@ use android_system_composd::binder::{ self, BinderFeatures, ExceptionCode, Interface, Status, Strong, ThreadState, }; use anyhow::{Context, Result}; -use compos_common::COMPOS_DATA_ROOT; use rustutils::{system_properties, users::AID_ROOT, users::AID_SYSTEM}; -use std::fs::{create_dir, File, OpenOptions}; +use std::fs::{File, OpenOptions}; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::AsRawFd; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::sync::Arc; pub struct IsolatedCompilationService { @@ -100,19 +98,12 @@ impl IsolatedCompilationService { } fn do_odrefresh_for_test(&self) -> Result { - let mut staging_dir_path = PathBuf::from(COMPOS_DATA_ROOT); - staging_dir_path.push("test-artifacts"); - to_binder_result(create_dir(&staging_dir_path))?; - let compos = self .instance_manager .start_test_instance() .context("Starting CompOS for odrefresh test")?; - self.do_odrefresh(compos, &staging_dir_path) - } - fn do_odrefresh(&self, compos: Arc, staging_dir_path: &Path) -> Result { - let output_dir = open_dir(staging_dir_path)?; + let output_dir = open_dir(composd_native::palette_create_odrefresh_staging_directory()?)?; let system_dir = open_dir(Path::new("/system"))?; // Spawn a fd_server to serve the FDs.