📜 ⬆️ ⬇️

Basics of security of the Android operating system. Native user space, part 1

Introduction


In this article I will try to consider security a little higher than the kernel, namely: how security works in Native user space. We will touch on the theme of the operating system boot process and consider the structure of the Android file system. As I already said, I am not very strong in Linux, so if you notice inaccuracies, then correct - teach me and improve the article. Since this topic is quite extensive, I decided to split it into two parts. In the first part, we will look at the process of loading the operating system and features of the file system. Anyone interested, welcome!



List of articles

Here are links to my articles from this topic:
  1. Basics of security of the Android operating system. Core level
  2. Basics of security of the Android operating system. Native user space, part 1
  3. Basics of security of the Android operating system. Native user space, part 2
  4. Basics of security of the Android operating system. Security at the Application Framework level. Binder ipc



What is meant by Native user space

Native user space refers to all user-space components that run outside the Dalvik Virtual Machine and that are not part of the Linux kernel.
')


Android file system


First, let's look at the structure of the Android file system. Although Android is based on the Linux kernel, we will not see the usual file system structure here. Let's run the emulator and see what we have. To do this, execute the command:

adb shell ls -al 

In my terminal for the emulator on Android 4.2, I see the following result:

 drwxr-xr-x root root 2013-04-10 08:13 acct drwxrwx--- system cache 2013-04-10 08:13 cache dr-x------ root root 2013-04-10 08:13 config lrwxrwxrwx root root 2013-04-10 08:13 d -> /sys/kernel/debug drwxrwx--x system system 2013-04-10 08:14 data -rw-r--r-- root root 116 1970-01-01 00:00 default.prop drwxr-xr-x root root 2013-04-10 08:13 dev lrwxrwxrwx root root 2013-04-10 08:13 etc -> /system/etc -rwxr-x--- root root 244536 1970-01-01 00:00 init -rwxr-x--- root root 2487 1970-01-01 00:00 init.goldfish.rc -rwxr-x--- root root 18247 1970-01-01 00:00 init.rc -rwxr-x--- root root 1795 1970-01-01 00:00 init.trace.rc -rwxr-x--- root root 3915 1970-01-01 00:00 init.usb.rc drwxrwxr-x root system 2013-04-10 08:13 mnt dr-xr-xr-x root root 2013-04-10 08:13 proc drwx------ root root 2012-11-15 05:31 root drwxr-x--- root root 1970-01-01 00:00 sbin lrwxrwxrwx root root 2013-04-10 08:13 sdcard -> /mnt/sdcard d---rx--- root sdcard_r 2013-04-10 08:13 storage drwxr-xr-x root root 2013-04-10 08:13 sys drwxr-xr-x root root 2012-12-31 03:20 system -rw-r--r-- root root 272 1970-01-01 00:00 ueventd.goldfish.rc -rw-r--r-- root root 4024 1970-01-01 00:00 ueventd.rc lrwxrwxrwx root root 2013-04-10 08:13 vendor -> /system/vendor 

I will note here only the main directories and those that will be useful to us in the future. On the Internet, you can find a description and purpose of other directories. You may notice that some directories are the same as in Linux, for example, / dev , / proc , / sys , / mnt , / etc And their purpose is basically the same as in Linux. By the way, note that we do not see the / bin and / lib directories. Where they disappeared, I will tell a little later.

On the other hand, you can notice directories that are not in Linux at all. Among them we are interested in / data , / system , / cache , / init , /init.rc. Let's consider their purpose in more detail.
/ system This is the main directory where the unchanged components of the Android system are stored. If you draw an analogy, then this folder is similar to the folder C: \ windows \ , read-only. Those. we cannot change the data in this directory. Just here you can find the directories / bin and / lib , where various executable files and shared libraries are stored. In addition, here are the system applications that are built into the OSes and which, by default, can not be deleted. The contents of this directory are compiled during the compilation of the operating system.
/ data Since / system is available only for reading, then there should be a directory where the changeable data is stored. / data is what it is. For example, apk files of installed applications are saved to this directory in / data / app , and their data is stored in / data / data (we examined this directory in detail in the last article).
/ cache This is just a temporary storage. Also in this directory are saved, and then from it system updates are launched.

To understand what the / init file is and why we need incomprehensible files with the * .rc extension, consider the system boot process.



Android download process





Let's take a look at a few steps in the boot process of the Android operating system. This picture is taken from the book “Embedded Android”, there you can also find a more detailed description. Although in general I understand the process, but for me it’s more magic :)

CPU. When you press the power button, voltage is applied to the processor on your device. Since up to this point the processor has been turned off, and since it is not able to maintain its state without supplying voltage, then immediately after the start it is in some uninitialized state. In this case, the processor reads some hard-wired address from its special register and starts to execute instructions starting from it. Most often, this address points to the chip in which the bootloader (bootloader) is sewn.
Bootloader Bootloader initializes RAM and loads the Linux kernel into it. Additionally, Bootloader creates a RAMdisk.
Linux kernel. The kernel initializes various subsystems, embedded drivers, and mounts the root filesystem (the root filesystem). After that, the kernel can run the first program.
At this magic ends and then everything becomes more or less clear.



Init


The first program in the case of Android is init . The executable file is located in the root directory ( / init ). This program starts the kernel after its download. Its sources are located in the system / core / init / folder . Let's dig a little into them. We are interested in system / core / init / init.c :

 ... int main(int argc, char **argv) { ... /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we will * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); ... init_parse_config_file("/init.rc"); ... } 

First, we create and mount some of the necessary directories for the work, and then parse the /init.rc file and execute what we parse. The format of the /init.rc file is very well described in the readme , where you can also find an example. In short, this file is a set of actions (sections - a named sequence of commands). Each sequence of commands is triggered by a specific trigger (trigger). For example, the following sequentially is an action, in which trigger is fs, and a sequence of commands is a set of mount commands:

 on fs # mount mtd partitions # Mount /system rw first to give the filesystem a chance to save a checkpoint mount yaffs2 mtd@system /system mount yaffs2 mtd@system /system ro remount mount yaffs2 mtd@userdata /data nosuid nodev mount yaffs2 mtd@cache /cache nosuid nodev 

The source file /init.rc is located in system / core / rootdir / init.rc. Let's look at some of its main parts, although I strongly advise you to view it in its entirety. After that, many things you should be clear. So, our file begins with the following lines:

 import /init.usb.rc import /init.${ro.hardware}.rc import /init.trace.rc 

They mean that in addition to the init.rc file, you also need to import settings from the files init.usb.rc , init.trace.rc and from a file with an incomprehensible name init. $ {Ro.hardware} .rc However, $ {ro.hardware} - it's just a variable, a value that determines the type of iron. In the case of an emulator, its value, for example, is goldfish . Next, the environment variables are determined:

 ... on init ... # setup the global environment export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin export LD_LIBRARY_PATH /vendor/lib:/system/lib export ANDROID_BOOTLOGO 1 export ANDROID_ROOT /system export ANDROID_ASSETS /system/app export ANDROID_DATA /data export ANDROID_STORAGE /storage export ASEC_MOUNTPOINT /mnt/asec export LOOP_MOUNTPOINT /mnt/obb export BOOTCLASSPATH /system/framework/core.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar ... 

After this, the variables necessary for the operation of the device are initialized. If you are interested in this topic, then you can easily find information about a particular command. Let's take a closer look at the following block (which I have already cited in this article):

 on fs # mount mtd partitions # Mount /system rw first to give the filesystem a chance to save a checkpoint mount yaffs2 mtd@system /system mount yaffs2 mtd@system /system ro remount mount yaffs2 mtd@userdata /data nosuid nodev mount yaffs2 mtd@cache /cache nosuid nodev 

MTD - Memory Technology Devices. If in general terms, then MTD is a special chip with non-volatile (i.e., data on this chip is saved after a reboot or shutdown) flash-memory (such as NOR or NAND), on which disk images are saved. This article describes in more detail about this type of device, as well as limitations. Especially for these types of flash-memory, special file systems have been developed, for example, YAFFS. One of the most important limitations of these types of memory is that in order to write data to a sector where some data has already been written, you must first completely erase the entire sector. Therefore, manufacturers began to switch to a new type of block flash-memory (eMMC), on which you can put a regular ext4 file system and get rid of this restriction. Since I am showing an example of the init.rc file for the emulator, where all the work is emulated, then it defaults to the YAFFS2 file system (I think these are remnants of the past, because YAFFS2 was used for all devices up to Android 2.2). In a real device (this is just one of the examples when you need to use the init.rc file for a specific hardware), these commands will be overwritten. For example, in the case of the herring device (Google Nexus S), in the init.herring.rc file , this section looks like this:

 on fs mkdir /efs 0775 radio radio mount yaffs2 mtd@efs /efs noatime nosuid nodev chmod 770 /efs/bluetooth chmod 770 /efs/imei mount_all /fstab.herring ... 

Where fstab.herring is a file whose contents look like this:

 ... /dev/block/platform/s3c-sdhci.0/by-name/system /system ext4 ro wait /dev/block/platform/s3c-sdhci.0/by-name/userdata /data ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,encryptable=/efs/userdata_footer 

As you can see, / system , / data , / cache are simply mounting points (file system mount points) that point to either an MTD device (in the case of an emulator) or block devices (in the case of a real device) where corresponding disk images (system.img, userdata.img and cache.img). I'm not sure, but I think that inside the smartphone there is a single chip with flash-memory, divided into partitions (volumes), each of which contains the corresponding image. This flash memory chip is what we know by the name Internal storage , the volume of which is one of the basic parameters of a smartphone.

It should be noted that / system is mounted read-only (read only). This means that the content of this section does not change during the operation of the device, but only when you, for example, update the system on your device (using system updates).

We continue to consider our init.rc. The trigger post-fs-data forms the basic structure of the file system / data partition. There, in general, everything is clear - a set of mkdir , chown , chmod commands.

Further init.rc starts some demons. If you go back to the picture at the beginning of the article, they are listed in the Native daemons block. We’ll stop on this for now. As you can see from the figure, I did not fully consider the process of loading the operating system. Some uncovered stages I will discuss in the following article.



Conclusion


In the next part, I’ll tell you where the system.img, userdata.img and cache.img images come from and consider security at the Native user space level. As always, corrections, additions, as well as suggestions about what to write are welcome. And although I already have some plan about what to write in the following article, I am ready to correct it.


Links


  1. Working with MTD Devices
  2. "Embedded Android" by Karim Yaghmour
  3. Android Security Underpinnings by Marko Gargenta



Update

Source: https://habr.com/ru/post/176131/


All Articles