Build Milkomeda from Source
Copyright (c) 2018 University of California, Irvine. All rights reserved.
See our Milkomeda paper for technical details. Authors: Zhihao Yao, Saeed Mirzamohammadi, Ardalan Amiri Sani, Mathias Payer
This document is shared under the GNU Free Documentation License WITHOUT ANY WARRANTY. See https://www.gnu.org/licenses/ for details. The build instructions are based on Google's guide to building Chromium on Linux and The LineageOS Project's guide to build for bullhead.
- At least 200 GB of free disk space, and another 100 GB if you wish to build Chromium WebGL security checks from source.
- A relatively recent 64-bit Intel computer, preferably 16GB+ RAM.
- Ubuntu 16.04 LTS. Other distributions are mostly unsupported by Google's build tools.
- A Nexus 5X smartphone.
It is recommended to backup your system before proceeding.
Install Build Tools
To install build dependencies, Android platform tools, and
sudo apt-get install openjdk-8-jdk sudo apt-get install bc bison build-essential ccache curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev
repo and Android platform tools by running:
mkdir ~/bin; cd ~/bin wget https://dl.google.com/android/repository/platform-tools-latest-linux.zip unzip platform-tools-latest-linux.zip -d ~/bin/ rm platform-tools-latest-linux.zip echo "# set Android SDK platform tools path" >> ~/.profile echo "if [ -d \"\$HOME/bin/platform-tools\" ] ; then" >> ~/.profile echo " PATH=\"\$HOME/bin/platform-tools:\$PATH\"" >> ~/.profile echo "fi" >> ~/.profile source ~/.profile curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo
Get the code
You will need to create a Milkomeda home folder (e.g.
cd to the folder. The rest of this section assumes you are in the folder. Run:
mkdir ~/bullhead_milkomeda cd ~/bullhead_milkomeda repo init -u https://github.com/LineageOS/android.git -b cm-14.1
Fetch the code by running:
This will take a while. When it is done, run:
source build/envsetup.sh breakfast bullhead
Now you are ready to pull Milkomeda repositories. First, we need to get additional build tools, scripts, and prebuilt binaries by running:
# Make sure you are in Milkomeda home folder git clone https://github.com/trusslab/milkomeda_tools_binaries.git mv ./milkomeda_tools_binaries/* ./ rm -rf ./milkomeda_tools_binaries
Next, pull Milkomeda repositories by typing:
cd external/jemalloc/ git remote add origin https://github.com/trusslab/milkomeda_bullhead_jemalloc.git git checkout 836d536 git pull origin release git checkout 836d536 cd - cd frameworks/native/ git remote add origin https://github.com/trusslab/milkomeda_bullhead_native.git git checkout c2e8ee8 git pull origin release # Git will prompt a merge message. Press Ctrl-C to exit. git checkout c2e8ee8 cd - cd frameworks/base/ git remote add origin https://github.com/trusslab/milkomeda_bullhead_base.git git checkout 7467536 git pull origin release git checkout 7467536 cd - cd kernel/lge/bullhead/ git remote add origin https://github.com/trusslab/milkomeda_bullhead_kernel.git git checkout cdc93dc git pull origin release git checkout cdc93dc cd - cd bionic/ git remote add origin https://github.com/trusslab/milkomeda_bullhead_bionic.git git checkout d207f78 git pull origin release git checkout d207f78 cd - # Our development is based on the cm-14.1 branch (2017-08). # Some repositories receive updates since then. # We need to checkout them back to an older version to avoid compiler errors. cd external/skia git checkout da4a326 cd - cd packages/apps/CMParts git checkout 8ba6fe3 cd - cd packages/providers/MediaProvider git checkout 03abed5 cd - cd packages/providers/DownloadProvider git checkout 581eab3 cd - cd packages/apps/Settings git checkout 2701395 cd - cd packages/apps/PackageInstaller git checkout 1b36092 cd -
Build System Image
This section builds a clean system image. You must completely build it at least once before building Milkomeda programs, otherwise the compiler will complain about missing files later.
To start the build, run:
source build/envsetup.sh breakfast bullhead croot brunch bullhead
Note: Do not flush your Nexus 5X with this build unless you have retrieved device-specific blobs. Please see The LineageOS Project's guide to build for bullhead for a complete guide.
Note: If Jack (Java compiler) runs out of memory, run this command and reboot.
echo "export ANDROID_JACK_VM_ARGS=\"-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4G\"" >> ~/.bashrc
Note: If compiling fails due to missing binaries in
out/host/linux_x86/bin/, run this command and retry:
mv host/* out/host/linux-x86/bin/
Build Milkomeda Kernel
Note: Kernel must be built with unmodified
external/jemalloc repositories. If you want to build kernel later, make sure these repository HEADs are pointed to the correct commits:
cd bionic git checkout d207f78 cd - cd external/jemalloc git checkout 836d536 cd -
To start the build, run:
cd kernel/lge/bullhead/ git checkout release cd - source build-kernel.sh
Note: to run Milkomeda, you must disable SELinux (or set it to
permissive mode ) temporarily. We have already set it to
permissive mode in the kernel. See changes in
Build Milkomeda User Space Programs
First, we need to switch the following repositories to our Milkomeda branch. Make sure you are in Milkomeda root folder. Run:
cd external/jemalloc/ git checkout release cd - cd frameworks/native/ git checkout release cd - cd frameworks/base/ git checkout release cd - cd bionic/ git checkout release cd - source build-milkomeda-all.sh
Build Security Checks (Optional)
We have already populated
<Milkomeda home>/chr_libs with prebuilt binaries. If you prefer to use the prebuilt binaries, simply skip this section.
This section provides guides to build the Chromium WebGL security checks into dynamic libraries. Once the build finishes, you will need to copy the libraries to
Even if you already have Chromium
depot_tools, you still need to clone our repository. Get
milkomeda_depot_tools by running:
git clone https://github.com/trusslab/milkomeda_depot_tools.git cd milkomeda_depot_tools git apply prevent_update.diff cd ..
You might want to add the path to
depot_tools to your
Note: do not use
~ on PATH, otherwise the later commands will fail. Rather, you should use either
$HOME or the absolute path:
Note: If you have previously installed Chromium
depot_tools, you might want to update your
~/.bashrc with the new path.
Fetch Milkomeda Chromium
chromium directory and
cd to it (you can call this whatever you like and put it wherever you like, as long as the full path has no spaces. Below we assume the path is
mkdir ~/chromium && cd ~/chromium
Run the following command to fetch the code and its dependencies:
fetch --nohooks chromium
n when it prompts
OK to update it to https://chromium.googlesource.com/chromium/tools/depot_tools.git ? [Y/n].
fetch will clone the repository at
src. This command might take a while depending on your Internet connection. Expect a few hours.
The remaining instructions assume you are in
Install Android build dependencies
To install the build tools, run:
# type 'yes' if the script asks for installing dev software build/install-build-deps-android.sh
These command will download additional binaries and dependencies:
echo "target_os = [ 'android' ]" >> ../.gclient gclient sync
Setup the build
To set up a new build, run:
gn gen out/decoder
Note: this will create
~/chromium/out/decoder. You can rename
decoder whatever you want, just make sure it is under
gn args out/decoder
The command will automatically open a config file with
vim. Append the following lines to the file:
target_os = "android" target_cpu = "arm64" is_debug = false dcheck_always_on = false is_component_build = true
Build WebGL security checks
To build, run:
ninja -C out/decoder/ gpu/command_buffer/service:service
Note: to speed up your build, you might want to add
-j flag to enable multi-thread. For example,
ninja -j16 -C out/decoder/ gpu/command_buffer/service:service
Once the build finishes, copy
Install system image
Install instructions are available here. Please follow the guide to unlocking the bootloader, Install a custom recovery, and install the
.zip file using
adb sideload. Please wipe the phone completely before the installation.
After a successful installation, enable
Developer Options by clicking
About Phone ->
Build Number seven times, then enable
Android Debug and
ADB root access in
To install Milkomeda, run:
# Make sure you are in Milkomeda root folder source setup_blobs.sh source install-milkomeda-all.sh source install-kernel.sh
Note: If you rebuild kernel, please make sure to
git checkout back the Milkomeda repositories, and rebuilt them with
install-milkomeda-all.sh assumes all Milkomeda binaries are up-to-date.
lib65 contains binaries that we manually modified with
sed. For enhanced security, the graphics libraries and most of their dependencies will use libt (a second libc loaded in the secure domain) instead of the insecure libc. A list of replaced libraries is available here.
Note: every time the
framework.jar is modified, the next boot will take longer. Expect a few minutes.
Install test cases
Next, build and install OpenGL applications with
Android Studio. Download the applications code by cloning:
Note: We use Android Studio version 3.1.3, SDK API level 25, and NDK version r14b. Other versions should also work, but we haven't tested.
Note: We included a GL3JNI library path in
<Milkomeda_home_path>/frameworks/base/cmds/app_process_milkomeda/shield.cpp. Please make sure you have installed GL3JNI before running Milkomeda with any other applications. To make sure we have the correct application path, please manually uninstall an application before installing it again. Alternatively, you can remove the GL3JNI library path from
shield.cpp and still run other test cases.
Switch to your Milkomeda home folder. Open a new terminal (to avoid using a different
adb after a build) and run:
adb root; adb logcat
Now, close the phone's display by pressing the side button. Open another terminal, launch a test case by running the corresponding script. You can
launch*.sh scripts to see which application a script will launch. Once the script has finished its execution, open the phone's display and swipe up to unlock the screen.
source launch.sh # or launch2.sh
For the Learn-OpenGLES-Tutorials test cases (
launch_lesson7.sh), wait for around 3 seconds after the launch script has finished its execution, and then open the phone's display and swipe up to unlock the screen.
source launch_lesson5.sh # or launch_lesson7.sh
Note: Reboot after every run.
Note: Do not use a password which will delay the screen unlock.
adb fails due to permission errors, check if you have allowed USB debug access from your machine. You might also need to enable
Use USB to Transfer files from the swipe-down menu every time the phone reboots.
A Note on checkGen
If you have followed all the above instructions, congratulations, you already have a Chromium and Android source tree with all security checks in place. If you wish to port WebGL security checks from Chromium yourself, you can try our open-sourced checkGen tools:
git clone https://github.com/trusslab/milkomeda_checkgen.git cd milkomeda_checkgen # Configurate your Chromium and Android path in gles_patcher.py # Make sure your Chromium and framework/native does not have any Milkomeda commits
Create a copy of GLES2 libs by typing:
cp -r <Milkomeda home>/framework/native/opengl/libs <Milkomeda home>/framework/native/opengl/medalibs
Now, you are ready to run checkGen:
Note: The word
yaap in our code stands for Yet Another Automatic Patcher.
Note: checkGen is not production-ready. The comments in
gles_patcher.py have more details on how to use the generated code.
Known issues and future work
- We have not ported the checks for extension and platform-specific OpenGLES APIs. They are not used in our test cases, but we plan to support them in the future.
- There is a small chance that Milkomeda fails to run. If you see a blank screen with no apparent error in
adb logcat, please reboot the phone and retry.
- Running Milkomeda requires the screen to be closed until the launch process is complete. We plan to resolve this issue.
This work (i.e., design and implementation of Milkomeda) was supported by NSF awards #1617513, #1513783, and ONR award N00014-17-1-2513.