<<

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 (.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: OS Framework

■ Recursive system structure ■ Hierarchical System ▪ Root: Microkernel Architecture ▪ Parent: Responsibility + control ▪ Isolation is default ▪ Strict communication policy ■ Everything is a user- ▪ 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//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 ... [init -> libutils_test] Note: Google Test filter = -VectorTest.SetCapacity_Overflow:VectorTest._grow_OverflowSize [init -> libutils_test] :VectorTest._grow_OverflowCapacrstr16EmptyTarget_bug:SystemClock.SystemClock [init -> libutils_test] [======] Running 61 tests from 9 test cases. [init -> libutils_test] [------] Global test environment set-up. [init -> libutils_test] [------] 3 tests from VectorTest [init -> libutils_test] [ RUN ] VectorTest.CopyOnWrite_CopyAndAddElements [init -> libutils_test] [ OK ] VectorTest.CopyOnWrite_CopyAndAddElements (2 ms) ... [init -> libutils_test] [ PASSED ] 61 tests. [init] child "libutils_test" exited with exit value 0 Run script execution successful. make: Leaving '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 ▪ 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 => 1, specification of binary messages Msg_Error => 3) with Size => 2; type Length is mod 2**14; ▪ 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 => Length * 8; Value : Payload; talk for details (Saturday, 11:30, end message; 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" : int "/dev/hwbinder" Pathname: String ? = 0 "/dev/vndbinder" Flags: Int : int FD : Int Open flags Binder requests Request : Unsigned_Long O_RDWR BINDER_WRITE_READ Perform / operation Data : Pointer ■ Linux device node /dev/[vnd|hw|]binder BINDER_SET_MAX_THREADS Set maximum number of binder threads BINDER_SET_CONTEXT_MGR Become context manager

BINDER_THREAD_EXIT Exit a binder thread

BINDER_VERSION Retrieve binder version

Binder data

binder_write_read Request = BINDER_WRITE_READ ▪ Interaction through interface Write_Size : Signed_Long Bytes to write ioctl() Write_Consumed : Signed_Long Bytes consumed by kernel driver size Write_Buffer : Pointer Pointer to write buffer Read_Size : Signed_Long Bytes to read Read_Consumed : Signed_Long Bytes consumed by kernel driver Read_Buffer : Pointer Pointer to read buffer

binder_set_max_threads Request = BINDER_SET_MAX_THREADS Unsigned_32 Maximum number of threads

▪ Blocking or non-blocking binder_version Request = BINDER_VERSION Protocol_Version : Signed_32 Driver protocol version

void Request = BINDER_THREAD_EXIT

void Request = BINDER_SET_CONTEXT_MGR

▪ Send and/or receive phase Binder_Driver_Command_Protocol BC_TRANSACTION

BC_REPLY

BC_FREE_BUFFER

BC_INCREFS

BC_ACQUIRE

BC_RELEASE

BC_DECREFS ■ Data is passed via linked data structure BC_INCREFS_DONE BC_ACQUIRE_DONE

BC_REGISTER_LOOPER

BC_ENTER_LOOPER

BC_EXIT_LOOPER

BC_REQUEST_DEATH_NOTIFICATION

BC_CLEAR_DEATH_NOTIFICATION Binder transaction BC_DEAD_BINDER_DONE ▪ Local/remote objects with reference counting Command : Unsigned_32 BC_TRANSACTION_SG binder_transaction_data BC_REPLY_SG Command = BC_TRANSACTION ∨ Command = BC_REPLY : U32 Descriptor for remote objects Ptr: Pointer Pointer to local objects Cookie : Pointer Target object cookie Transaction flags Code : U32 Remote method ID TF_ONE_WAY One-way call, asynchronous, no return Flags : U32 Flags TF_ROOT_OBJECT Contents are the components root object Sender_PID : Pid Sender process ID TF_STATUS_CODE Contents are a 32-bit status code Sender_EUID : Uid Effective user ID of sender TF_ACCEPT_FDS Allow replies with file descriptors ▪ Special objects Data_Size : Size Number of bytes of data size Offsets_Size: Size Number of bytes of offsets Buffer: Pointer Transaction data Buf: U8 (8) Inline data size Offsets : Pointer Offsets from buffer to flat_binder_objects struct

binder_uintptr_t Command = BC_FREE_BUFFER Data buffer Pointer to transaction data received on a read. 0000 binder int 0010 ... ∨ ∨ ∨ ▪ File-descriptor passing Offsets Command = BC_INCREFS Command = BC_ACQUIRE Command = BC_RELEASE Command = BC_DECREFS Binder types 0020 ... Obtain/release a strong/weak reference Offset 1 BINDER_TYPE_BINDER 0030 weak_binder Offset 2 binder_ptr_cookie 0035 weak_binder Command = BC_INCREFS_DONE ∨ Command = BC_ACQUIRE_DONE BINDER_TYPE_WEAK_BINDER Offset 3 0050 ... Obtaining weak/strong reference done Offset 4 BINDER_TYPE_HANDLE 0060 handle Offset 5 no parameters 0100 weak_handle Command = BC_REGISTER_LOOPER BINDER_TYPE_WEAK_HANDLE Offset 6 0120 handle Register a spawned looper thread with the device. Offset 7 BINDER_TYPE_FD 0128 fd Offset 8 no parameters ▪ Linux kernel copies between processes 0132 fd Command = BC_ENTER_LOOPER ∨ Command = BC_EXIT_LOOPER BINDER_TYPE_FDA Offset 9 0140 fda Called when an application-level thread enters and exits the binder loop, respectively. Offset 10 BINDER_TYPE_PTR 0220 ptr Offset 11 binder_handle_cookie ...... Command = BC_REQUEST_DEATH_NOTIFICATION ∨ Command = BC_CLEAR_DEATH_NOTIFICATION ... 0eff2 ptr Set up or clear a death notification for a handle

binder_uintptr_t Command = BC_DEAD_BINDER_DONE

Death notification done

▪ Name-service application (ServiceManager) binder_transaction_data_sg Command = BC_TRANSACTION_SG ∨ Command = BC_REPLY_SG Scatter-gather transaction Transaction_Data : binder_transaction_data Transaction data Buffer_Size : Size Buffer size

2020-02-02 25 Android IPC Idea: User-level message broker

■ Verified broker component to handle binder transactions ▪ Android apps are client of broker using message passing ▪ Clients share memory region with broker ▪ Broker implements name service and copies between clients ■ Pros ▪ No additional complexity in the kernel ▪ Enables filter components / policies ■ Cons ▪ At least 3 copies per transaction (Android kernel needs 1)

2020-02-02 26 Conclusions

■ Future Work ■ Conclusions ▪ User-level binder IPC on Genode ▪ Rehosting Android Runtime to Genode is feasible ▪ Porting or emulation of required Android services ▪ Easy porting due to declarative nature of Androids build system ▪ Integration into Genodes Nitpicker UI subsystem ▪ Googles extensive test suite is extremely helpful ▪ Trusted filters (e.g. encrypted / tagged calendar entries) ▪ Environment for trustworthy formally verified filters exists ▪ Test complex, unmodified Android applications on Genode

2020-02-02 27 Questions?

Alexander Senier [email protected]

@Componolit · componolit.com · github.com/Componolit

2020-02-02 28