A Component-Based Environment for Android Apps
Total Page:16
File Type:pdf, Size:1020Kb
A Component-based Environment for Android Apps Alexander Senier FOSDEM, Brussels, 2020-02-02 Smartphone Trust Challenges Privilege Escalation 2020-02-02 2 Media Frameworks are not getting simpler. How do we avoid such fatal errors? 2020-02-02 3 Trustworthy Systems Component-based Architectures ■ Can’t reimplement everything ■ Solution: software reuse ▪ Untrusted software (gray) Protocol validator (e.g. Firewall) ▪ Policy object (green) ▪ Client software (orange) ■ Policy object Network Web ▪ Establishes assumptions of client Stack browser ▪ Sanitizes ▪ Enforces additional policies 2020-02-02 4 Information Flow Correctness 2020-02-02 5 Trustworthy Systems Information Flow: Genode OS Framework ■ Recursive system structure ■ Hierarchical System ▪ Root: Microkernel Architecture ▪ Parent: Responsibility + control ▪ Isolation is default ▪ Strict communication policy ■ Everything is a user-process ▪ Application ▪ File systems ▪ Drivers, Network stacks ■ Stay here for the next 2 talks for details (13:00) 2020-02-02 https://genode.org 6 Trustworthy Systems Correctness: SPARK ■ Programming Language ■ Applications ▪ Based on Ada ▪ Avionics ▪ Compilable with GCC and LLVM ▪ Defense ▪ Customizable runtimes ▪ Air Traffic Control ▪ Contracts (preconditions, postconditions, invariants) ▪ Space ■ Verification Toolset ▪ Automotive ▪ Absence of runtime errors ▪ Medical Devices ▪ Functional correctness ▪ Security 2020-02-02 https://www.adacore.com/about-spark 7 Applying this Approach to Android Apps 2020-02-02 8 GART Project Objectives ■ Unmodified Android Apps ■ On top of Genode OS Framework ■ Formally-verified policy objects 2020-02-02 9 GART Project Elements ■ Build system ■ Android Runtime ■ Trusted Proxies ■ IPC 2020-02-02 10 Build System Integration 2020-02-02 11 Build System Integration Android Build Files ■ Soong replaced old make-based build system in Oreo (8.0) ■ JSON-like blueprint files cc_binary { ■ Purely declarative – no name: "gzip", conditionals, no control flow srcs: ["src/test/minigzip.c"], ■ Complex cases handled in Go shared_libs: ["libz"], application stl: "none", } ■ Manifests for the Ninja build system are generated 2020-02-02 12 Build System Integration Translating Android Build Files $ gnoos -b android -i libnativehelper/Android.bp -o libnativehelper.mk -p LIBNATIVEHELPER_ \ '/cc_library[@name=libnativehelper]' $ cat libnativehelper.mk LIBNATIVEHELPER_CFLAGS = -Werror -fvisibility=protected LIBNATIVEHELPER_EXPORT_HEADER_LIB_HEADERS = jni_headers jni_platform_headers libnativehelper_header_only LIBNATIVEHELPER_EXPORT_INCLUDE_DIRS = include LIBNATIVEHELPER_HEADER_LIBS = jni_headers jni_platform_headers libnativehelper_header_only LIBNATIVEHELPER_HOST_SUPPORTED = True LIBNATIVEHELPER_NAME = libnativehelper LIBNATIVEHELPER_SHARED_LIBS = liblog LIBNATIVEHELPER_SRCS = JNIHelp.cpp JniConstants.cpp JniInvocation.cpp toStringArray.cpp 2020-02-02 13 Build System Integration Integrating Android Build Files (1) ■ Gnoos has been integrated into Genode build system ■ Consistent with regular Genode applications ▪ Library build files are in lib/mk ▪ Library import files are in lib/import ▪ Applications have a target.mk 2020-02-02 14 Build System Integration Integrating Android Build Files (2) ■ Porting native Android applications is easy ■ With run script, they can be run as every other Genode application ■ makes porting Android tests a one-liner gart_gtest_main $ make -C build/arm_v8a run/test/libutils AAB [init A> libutils_test] Note: Google Test filter = -VectorTest.SetCapacity_Overflow:VectorTest._grow_OverflowSize [init A> libutils_test] :VectorTest._grow_OverflowCapacrstr16EmptyTarget_bug:SystemClock.SystemClock [init A> libutils_test] [==========] Running 61 tests from 9 test cases. [init A> libutils_test] [----------] Global test environment set-up. [init A> libutils_test] [----------] 3 tests from VectorTest [init A> libutils_test] [ RUN ] VectorTest.CopyOnWrite_CopyAndAddElements [init A> libutils_test] [ OK ] VectorTest.CopyOnWrite_CopyAndAddElements (2 ms) AAB [init A> libutils_test] [ PASSED ] 61 tests. [init] child "libutils_test" exited with exit value 0 Run script execution successful. make: Leaving directory 'build/arm_v8a' 2020-02-02 15 Android Runtime 2020-02-02 16 Android Runtime Dependencies libvixld-arm libsigchain libvixld-arm64 art_libdexfile_tests libartd-disassembler art_runtime_tests libart-gtest libart-compiler-gtest art_runtime_compiler_tests liblz4 libgtest_prod libicui18n libnativehelper libicuuc libart-runtime-gtest libmetricslogger libartd-compiler libicuuc_stubdata libartd libnativeloader libnativebridge liblog libgtest libbase libartbased liblzma libcutils libbacktrace libdemangle libasync_safe libtombstoned_client libvndksupport libdexfiled libziparchive libz libutils libdl ld-android 2020-02-02 17 Android Runtime Components ■ dalvikvm ▪ Only ~200 LOC ▪ Linked with only few libraries – , , libsigchain libnativehelper libc ■ Item1▪ : interception layer for signals libsigchain ■ Titem2▪ : helpers for Java/native interface libnativehelper ■ ▪libartSubitem ▪ Actual Java Virtual Machine ▪ Loaded dynamically by dalvikvm ▪ > 50 dependencies that needed to be ported 2020-02-02 18 Android Runtime Current State ■ dalvikvm and libart ported to Genode ▪ The ~1000 tests cases of dependencies succeed ▪ Most of the ~500 ART test cases succeed ■ ▪Item1Runtime fully initializes and starts Java program on Genode/arm_v8a ■ Titem2(and then crashes, see below ;) ■ ▪OpenSubitem issues ▪ Concurrency bugs due to missing futex implementation ▪ Probably some more due to differences between Genodes libc and Linux ▪ Runtime-compiler basically ported, but still has issues 2020-02-02 https://github.com/Componolit/gart 19 Trusted Proxies 2020-02-02 20 Trusted Proxies Component Environment ■ Gneiss component library ■ Downsized SPARK/Ada runtime ▪ Fully asynchronous, event-driven ▪ Optimized for critical low- and platform-independent complexity components ▪ Support for Genode, Muen and ▪ No allocators, no exception Linux handlers, no implicit dynamic ▪ Only constructs that are formally code, no tasking... verifiable with SPARK proof tools ▪ Support for Genode, Muen and ▪ Generic interfaces: Log, timer, Linux block device, message, shared ▪ Easy to customize and port to memory new (embedded) environments ■ See recordings of previous talk by Johannes Kliemann for details 2020-02-02 https://github.com/Componolit/ada-runtime | https://github.com/Componolit/gneiss 21 Trusted Proxies Verified Binary Parsers ■ RecordFlux package TLV is ▪ DSL and toolset for formal type Tag is (Msg_Data A> 1, specification of binary messages Msg_Error A> 3) with Size A> 2; type Length is mod 2ARFSQ ▪ Model verification (absence of contradictions, reachability, ...) type Message is message ▪ Generation of verifiable binary Tag : Tag then Length parsers if Tag = Msg_Data, then null ▪ Generation of message if Tag = Msg_Error; generators Length : Length then Value ■ See recording of Tobias Reihers with Length A> Length * 8; Value : Payload; talk for details (Saturday, 11:30, end messageQ security devroom) end TLV; 2020-02-02 https://github.com/Componolit/RecordFlux | https://arxiv.org/abs/1910.02146 22 Future Work / Next Up: Android IPC 2020-02-02 23 2020-02-02 24 Android IPC Binder device Binder devices "/dev/binder" open : int "/dev/hwbinder" Pathname: String ! " "/dev/vndbinder" Flags: Int ioctl : int FD : Int Open flags Binder requests Request : Unsigned_Long O_RDWR #I$D%R_WRI&%_R%'D Perform read/write operation Data : Pointer ■ Linux device node /dev/[vnd|hw|]binder #I$D%R_S%&_(')_&*R%'DS Set maximum number of binder threads #I$D%R_S%&_+O$&%)&_(,R Become context manager #I$D%R_&*R%'D_%)I& Exit a binder thread #I$D%R_-%RSIO$ Retrieve binder version Binder data binder_write_read Re./est ! #I$D%R_WRI&%_R%'D ▪ Interaction through interface Write_Size : Signed_Long B tes to write ioctl() Write_Consumed : Signed_Long B tes consumed b !erne" driver si5e Write_Buffer : Pointer Pointer to write bu#er Read_Size : Signed_Long B tes to read Read_Consumed : Signed_Long B tes consumed b !erne" driver Read_Buffer : Pointer Pointer to read bu#er binder_set_max_threads Re./est ! #I$D%R_S%&_(')_&*R%'DS Unsigned_01 $aximum number of threads ▪ Blocking or non-blocking binder_version Re./est ! #I$D%R_-%RSIO$ Protocol_Version : Signed_01 %river protoco" version void Re./est ! #I$D%R_&*R%'D_%)I& void Re./est ! #I$D%R_S%&_+O$&%)&_(,R ▪ Send and/or receive phase Binder_%river_,ommand_Protoco" #+_&R'$S'+&IO$ #+_R%PL4 #+_9R%%_#U99%R #+_I$+R%9S #+_'+;UIR% #+_R%L%'S% #+_D%+R%9S ■ Data is passed via linked data structure #+_I$+R%9S_DO$% #+_'+;UIR%_DO$% #+_R%,IS&%R_LOOP%R #+_%$&%R_LOOP%R #+_%)I&_LOOP%R #+_R%;U%S&_D%'&*_$O&I9I+'&IO$ #+_+L%'R_D%'&*_$O&I9I+'&IO$ Binder transaction #+_D%'D_#I$D%R_DO$% ▪ Local/remote objects with reference counting Command : Unsigned_01 #+_&R'$S'+&IO$_S, binder_transaction_data #+_R%PL4_S, +o223nd ! #+_&R'$S'+&IO$ ∨ +o223nd ! #+_R%PL4 Handle: U01 %escriptor for remote ob&ects Ptr: Pointer Pointer to "oca" ob&ects Cookie : Pointer 'arget ob&ect coo!ie 'ransaction flags Code : U01 Remote method (% &9_O$%_W'4 One>w3A c3ll@ 3sAnchrono/s@ no ret/rn Flags : U01 )"ags &9_ROO&_O#J%+& +ontents 3re the co2ponents root obKect Sender_PID : Pid Sender process (% &9_S&'&US_+OD% +ontents 3re 3 01>bit st3t/s code Sender_ !ID : Uid E#ective user (% of sender &9_'++%P&_9DS 'llow replies with Ble descriptors ▪ Special objects Data_Size : Si5e *umber of b tes of data si5e "ffsets_Size: Si5e *umber of b tes of o#sets Buffer: Pointer 'ransaction data Bu#: U6 768 (n"ine data