Exploring SE for Android (2015)

Chapter 4. Installation on the UDOO

In order to continue our exploration, we will need to get a tangible system in place to work with. In this chapter, we will:

·        Build Android 4.3 for the UDOO from source

·        Flash an SD card with our boot images

·        Get the UDOO running while capturing logs

·        Establish an adb connection to the UDOO

·        Rebuild the kernel with SELinux support

·        Verify our SELinux UDOO image works as expected

We will start with the publicly available UDOO Android 4.3 Jelly Bean source code, which can be downloaded from http://www.udoo.org/downloads/. It is assumed you have a UDOO and have verified that it is functional. It is recommended you follow the instructions on the UDOO website for getting started with the Android 4.3 prebuilt image as an initial test (for more information, refer to http://www.udoo.org/getting-started/).

You will also need an appropriate development system for working with Android and a UDOO, but the details of this are beyond the scope of this chapter. An appendix has been provided detailing the setup of a standard Ubuntu Linux 12.04 system to ensure you have the highest probability of success duplicating the work in this book.

Retrieving the source

Let's start this exercise by downloading the Android 4.3 Jellybean source code from the download links given in the preceding section, and extract the download into a workspace using the following commands:

$ mkdir ~/udoo && cd ~/udoo

$ tar -xavf ~/Downloads/UDOO_Android_4.3_Source_v2.0.tar.gz

Once this is done, you should review the UDOO documentation and the Android source code building instructions at the following URLs:

·        http://www.elinux.org/UDOO_compile_android_4-2-2_from_sources

·        http://source.android.com/source/initializing.html

The instructions provided by the preceding URL discuss how to build Android with Open JDK 7. However, these instructions are for the current release of Android (L preview) and are not 100 percent relevant. For Android 4.3, you must build with Oracle Java 6, which is archived by Oracle and found at http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html.

It is assumed that you have a duplicate of the system detailed in the AppendixThe Development Environment. That appendix, among other things, walks you through the setup of Oracle Java 6 as your only Java instance. However, for those who prefer to work from their existing systems, particularly those with multiple Java SDKs, please keep in mind you will need to ensure your system is using the Oracle Java 6 tools when working through the rest of this book.

Finish setting up your environment by changing to the root of your UDOO source tree and execute the following command:

$ . setup udoo-eng

Once the environment is configured, we need to build the bootloader:

$ cd bootable/bootloader/uboot-imx

$ ./compile.sh -c

A graphical menu will appear. Ensure the settings are as follows:

·        DDR Size: Select 1 Giga, bus size 64, and active CS \ 1 (256Mx4)

·        Board Type: Select UDOO

·        CPU type: Select quad-core or dual-core option, dependent on which system you have. We happen to be using the quad-core system.

·        OS type: Select Android

·        Environment device: Must select SD/MMC

·        Extra optionsCLEAN should be selected

·        Compiler options: Paths to tool chains can be selected here; just take the defaults

The following screenshot shows the graphical menu displayed by the preceding command:

Retrieving the source

When you exit, be sure to save. Then start the compilation:

$ ./compile.sh

Board type selected: UDOO

CPU Type: QUAD/DUAL

OS type: Android

...

/home/bookuser/udoo/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-objcopy -O srec u-boot u-boot.srec

/home/bookuser/udoo/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

Just to be safe, verify your build was successful by using ls u-boot.bin to ensure the bootloader image now exists. Now, build Android using the following command:

$ croot

$ make –j4 2>&1 | tee logz

The first command is something that was sourced in the setup scripts for Android and takes us back to the root of our project tree. The second command, make, builds the system. You should set the option for j to twice your CPU/core count in most cases. Because many of you might have a dual-core machine, we'll use –j4. One of the authors of this book uses 8 CPU cores, for example, and uses the flag -j16. The file redirection and tee commands capture the build output to a file. This is important to help and debug any build issues. This build, depending on your system can take a long, long time. On the previously mentioned 8-core system with 16GB RAM, this took a little over 35 minutes. On other systems, we've experienced build times over 3 hours.

In this case, capturing the logs proved very useful. The build terminated with an error, and by searching the logs for error, we found the following:

$ grep error logz

...

external/mtd-utils/mkfs.ubifs/mkfs.ubifs.h:48:23: fatal error: uuid/uuid.h: No such file or directory

external/mtd-utils/mkfs.ubifs/mkfs.ubifs.h:48:23: fatal error: uuid/uuid.h: No such file or directory

external/mtd-utils/mkfs.ubifs/mkfs.ubifs.h:48:23: fatal error: uuid/uuid.h: No such file or directory

...

By evaluating those errors, we discover we are missing headers for uuid and lzo1x. We can also open the Android makefile, external/mtd-utils/mkfs.ubifs/Android.mk, and determine the likely libraries involved from the line LOCAL_LDLIBS:= -lz -llzo2 -lm -luuid -m64. Searching reveals the specific Ubuntu package we're missing; we will install them and build again. The $ character at the end of the search string ensures we only get results ending in uuid/uuid.h. Without it, we might match files ending in .html or .hpp:

$ sudo apt-file search -x "uuid/uuid.h$"

uuid-dev: /usr/include/uuid/uuid.h

$ sudo apt-get install uuid-dev

$ make –j4 2>&1 | tee logz

A successful build should produce some final output similar to the following:

...

Running: mkuserimg.sh out/target/product/udoo/system out/target/product/udoo/obj/PACKAGING/systemimage_intermediates/system.img ext4 system 293601280 out/target/product/udoo/root/file_contexts

Install system fs image: out/target/product/udoo/system.img

out/target/product/udoo/system.img+out/target/product/udoo/obj/PACKAGING/recovery_patch_intermediates/recovery_from_boot.p maxsize=299747712 blocksize=4224 total=294120167 reserve=3028608

Flashing image on an SD card

With the bootloader, Android userspace, and Linux kernel built, it's time to insert an SD card and flash the images. Insert an SD card into your host computer, and ensure it's unmounted. In Ubuntu, removable media are mounted automatically, so you'll need to find the /dev/sd* device that is your flash drive, and umount it. For the remainder of the text, we will use /dev/sdd as the flash drive, but it is important to use the correct device for your system. If you have used this SD card for installing UDOO before, the card will contain multiple partitions, so you might see /dev/sdd<num> mounted numerous times:

$ mount | grep sdd

/dev/sdd7 on /media/vender type ext4 (rw,nosuid,nodev,uhelper=udisks)

/dev/sdd4 on /media/data type ext4 (rw,nosuid,nodev,uhelper=udisks)

/dev/sdd5 on /media/57f8f4bc-abf4-655f-bf67-946fc0f9f25b type ext4 (rw,nosuid,nodev,uhelper=udisks)

/dev/sdd6 on /media/cache type ext4 (rw,nosuid,nodev,uhelper=udisks)

$ sudo bash -c "umount /dev/sdd4 && umount /dev/sdd5 && umount /dev/sdd6 && umount /dev/sdd7"

Once the SD card is properly unmounted, we can flash our image:

$ sudo -E ./make_sd.sh /dev/sdd

Tip

You must use the -E parameter on sudo to preserve all the exported variables from the Android build. You must be in the same terminal session you built Android in. Otherwise you will see the error No OUT export variable found! Setup not called in advance….

Once this completes (it will take a while), it's important to flush the block device caches back to the disk with the command, sudo sync. Then, you can remove the SD card, insert it into the UDOO, and boot!

UDOO serial and Android Debug Bridge

Now that the UDOO is booting into Android, we want to make sure we can access it using the serial port as well as the Android Debug Bridge (adb). You'll need the UDOO serial drivers appropriate for your system. The details of this for Mac, Linux, and Windows can be found at

http://www.udoo.org/ProjectsAndTutorials/connecting-via-serial-cable/.

The serial port is the first form of communication that will come from the system, and it is initialized by the bootloader. It is a critical link for debugging any kernel or system issues that you encounter later on. It's also required in order to configure the USB port to allow adb connections across CN3 (the USB OTG port on the UDOO). To configure the port, we need to configure and use minicom to connect a shell to the device. Start by plugging a micro USB cable from CN6 (the micro USB port closest to the power button) to the host machine. Next, let's find the serial connection by looking through dmesg for the connection message of a TTY over USB.

$ sudo dmesg | tail -n 5

[ 9019.090058] usb 4-1: Manufacturer: Silicon Labs

[ 9019.090061] usb 4-1: SerialNumber: 0078AEDB

[ 9019.096089] cp210x 4-1:1.0: cp210x converter detected

[ 9019.208023] usb 4-1: reset full-speed USB device number 4 using uhci_hcd

[ 9019.359172] usb 4-1: cp210x converter now attached to ttyUSB0

Our TTY terminal is on the last line. Let's connect through it with minicom:

$ sudo minicom -sw

Select Serial Port Setup, type a, change Serial Device to /dev/ttyUSB0, and type f to toggle the hardware flow control off:

UDOO serial and Android Debug Bridge

To exit, hit Enter, select Save Setup and DFL, then select Exit from Minicom, and press Enter. Now run minicom to connect to your UDOO, and watch it boot:

$ sudo minicom -w

If the device is booted and running, you'll get a friendly root shell:

UDOO serial and Android Debug Bridge

If it's booting, you'll see the logs. Just wait for the root shell prompt:

UDOO serial and Android Debug Bridge

Now we need to flip some GPIO pins to move the CN3 micro USB into debug mode:

root@udoo:/ # echo 0 > /sys/class/gpio/gpio203/value

root@udoo:/ # echo 0 > /sys/class/gpio/gpio128/value

Then, reset the SAM3X8E processor that was using that bus, by removing and replacing the J16 jumper. Now plug in a micro USB cable from the host to CN3. You should now see a USB device as well as adb:

$ lsusb

Bus 001 Device 009: ID 18d1:4e42 Google Inc.

$ adb devices

List of devices attached

0123456789ABCDEF  offline

You need to select Allow USB debugging when the prompt appears on the UDOO Android side. When you do this, the device should go from offline to online; this way you can use adb.

Now test the connection and grab the screenshot over adb:

$ adb shell

root@udoo:/ #

$ adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen.png

This is the screenshot:

UDOO serial and Android Debug Bridge

At this point, we have a working development system. We have early boot logs and a rescue shell through the serial console. We also have an adb bridge with which we can use the standard Android debugging tools! There's nothing left to do but get this system secured with SELinux!

Flipping the switch

Now that we are enabling SELinux on the UDOO, we need to verify it isn't turned on. The way to do this is to check the known filesystem types in the /proc filesystem. SELinux has its own psuedo-filesystem, so if it's enabled, we should see it in the list:

$ adb shell cat /proc/filesystems

nodev  sysfs

nodev  rootfs

nodev  bdev

nodev  proc

nodev  cgroup

nodev  cpuset

nodev  tmpfs

nodev  debugfs

nodev  sockfs

nodev  pipefs

nodev  anon_inodefs

nodev  rpc_pipefs

nodev  devpts

  ext3

  ext2

  ext4

  cramfs

nodev  ramfs

  vfat

  msdos

nodev  nfs

nodev  jffs2

nodev  fuse

  fuseblk

nodev  fusectl

nodev  mtd_inodefs

nodev  ubifs

There is no evidence of SELinux here, so let's find the kernel configuration and turn it on. Execute this command from the ~/udoo/kernel_imx directory, and eventually you will be greeted with a graphical editing screen:

$ make menuconfig

First, you will need to enable Auditing support, as this is a dependency of SELinux. Under General setup | Auditing Support, enable Audit Support and Enable system-call auditing. Use the up and down arrow keys to highlight an entry, and press the spacebar to enable it. When an item is enabled, you will see an asterisk (*) next to it:

Flipping the switch

Go back to the main menu by selecting Exit... it's not very intuitive. Enter the File systems menu, and for each of the three filesystems, Ext2Ext3, and Ext4, ensure that Extended attributes and Security Labels are enabled. Then, go back to the main menu by selecting Exit:

Flipping the switch

From that screen, exit back to the main menu and go to Security Options. Once in the Security Options submenu, enable the Enable different security models and Socket and Networking Security Hooks options:

Flipping the switch

Once these are enabled, more options will appear. Enable NSA SELinux Support and ensure the other selections and values from the following screenshot are duplicated:

Flipping the switch

Finally, set Default security module to SELinux:

Flipping the switch

Once you select Default security module, a new window will appear from which you can select SELinux. Exit the configuration menus by selecting Exit until you are asked to save your new configuration:

Flipping the switch

Save the new configuration and write these changes to the originating kernel configuration file. Otherwise, it will be overwritten on subsequent builds. To do this, we'll need to discover which configuration file was used in the default build, which we built earlier before we made our own configuration with make menuconfig:

$ grep defconfig logz make -C kernel_imx imx6_udoo_android_defconfig ARCH=arm CROSS_COMPILE=`pwd`/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-

You can see that imx6_udoo_android_defconfig was used as the default configuration. Copy your custom configuration and build again:

$ cp .config arch/arm/configs/imx6_udoo_android_defconfig

$ croot

$ make –j4 bootimage 2>&1 | tee logz

A quick sanity check of the log file is always a good idea to verify SELinux was actually built into the kernel:

$ grep -i selinux logz

HOSTCC scripts/selinux/mdp/mdp

HOSTCC scripts/selinux/genheaders/genheaders

GEN security/selinux/flask.h security/selinux/av_permissions.h

CC security/selinux/avc.o

...

Now, with a built kernel supporting SELinux, insert the SD card into the host and run the following commands:

$ sudo -E ./make_sd.sh /dev/sdd

$ sudo sync

Tip

Don't forget to umount any automounted partitions from the SD card as we did before.

Plug the SD card into the UDOO, and fire it up. You should see logs over the serial console as we did before:

Flipping the switch

Eventually, the serial connection should take us to a root shell.

It's alive

How do we know that we have successfully enabled SELinux in the kernel? Earlier in this chapter, you ran the command, adb shell cat /proc/filesystems. We're going to do the same thing and look for a new filesystem called selinuxfs. If that is present, it indicates we have enabled SELinux successfully. Run the following command in the serial terminal:

# cat /proc/filesystems | grep selinux

nodev selinuxfs

We can see that selinuxfs is present! Another common practice is to check dmesg for any SELinux output. To do this, execute the following command via the serial terminal:

# dmesg | grep -i selinux

<6>SELinux: Initializing.

<7>SELinux: Starting in permissive mode

<7>SELinux: Registering netfilter hooks

<3>SELinux: policydb version 26 does not match my version range 15-23

<4>SELinux: Could not load policy: Invalid argument

Summary

This was a very exciting chapter. You learned how to enable SELinux in the kernel configuration, boot the "secured" system, and how to verify its presence. We also learned how to flash and build images for the UDOO in general and how to connect to it via serial and adb connections. In the next chapters, we will focus on how to make the UDOO usable with SE for Android capabilities.