1 | P a g e
Integrity Protection
On the Linux Based Android Platform
Kaiye Chang
kaiye@kth.se
Kungliga Tekniska Högskolan
Krisztina Barta
d03kba@student.lth.se Lunds Tekniska Högskola
Supervisors:
Per Ståhl (per.a.stahl@stericsson.com) Martin Hell (martin.hell@eit.lth.se) Christer Magnusson (cmagnus@dsv.su.se)
Fredrik Kilander (fki@kth.se)
Stockholm, Sweden 2014
2 | P a g e
Exclusively Kaiye Chang presented this version of the thesis and Krisztina Barta presented an earlier version in Lund 2009.
Division of the thesis report Kaiye Chang wrote the following parts:
Chapter 1 (excluding 1.1 and 1.2) Chapter 3.1.3, 3.1.4
Chapter 4.3 Chapter 5.2 Chapter 6 Appendices
And Krisztina Barta wrote the rest parts of the thesis:
Chapter 1.1, 1.2 Chapter 2
Chapter 3 (excluding 3.1.3 and 3.1.4) Chapter 4.1, 4.2
Chapter 5.1
Chapter 7
References
3 | P a g e
Abstract
Integrity protection on the Linux based Android Platform is examined. The secure boot
mechanism is studied and the verification of user space code is investigated. The task of this
master thesis was to extend the current code signing mechanism to include signing of files in
the file system, and code pages, and to implement verification of these files and pages. Proof-
of-concept solutions of two presented methods are implemented. It was found that the
integrity protection on the platform can be improved at a relatively reasonable cost by
verifying hashes of modules and programs before they are allowed to execute.
4 | P a g e
5 | P a g e
Sammanfattning
Integritetsskyddet på den Linux-baserade Android-plattformen undersöks. Den säkra boot- mekanismen studeras och verifiering av användarkod undersöks. Uppgiften för detta examensarbete var att utöka den aktuella signeringsmekanismen för att inkludera signering av filer i filsystemet och minnessidor, och att genomföra kontroll av dessa filer och sidor.
Prototyplösningar av två presenterade metoder implementeras. Det visade sig att integritetsskyddet på plattformen kan förbättras till en relativt rimlig kostnad genom att verifiera hashar av moduler och program innan de tillåts exekvera.
6 | P a g e
7 | P a g e
Acknowledgments
We would like to take this opportunity to thank all the people who gave generously of their time and expertise to make the very best of this master thesis.
Thanks to our supervisors from ST-Ericsson - Per Ståhl, Fredric Morenius, Joakim Bech and Martin Hovang who helped us tremendously.
Thanks to Christer Magnusson and Fredrik Kilander from KTH and Martin Hell from LTH who shows hope in the least hopeful moments.
We also want to acknowledge great reviewers, Fredrik Andersson and Magnus Andersson.
Great thanks to all above and also to everyone involved but not mentioned.
8 | P a g e
9 | P a g e
Table of Contents
Abstract ... 3
Sammanfattning ... 5
Acknowledgments ... 7
Table of Contents ... 9
Table of Figures ... 11
Glossary ... 13
Chapter 1: Introduction ... 15
1.1 Problem Statement ... 15
1.2 Purpose ... 15
1.3 Method ... 15
1.4 Risks, Ethics and Sustainable Development ... 16
1.5 Limitations ... 16
1.6 Audience ... 16
1.7 Structure of the Thesis ... 16
Chapter 2: Background ... 19
2.1 Public Key Cryptography ... 19
2.1.1 Signing ... 20
2.1.2 SHA-‐256 ... 21
2.1.3 RSA ... 21
2.2 Potential Attacks on Mobile Devices ... 22
2.3 ST-‐Ericsson’s Security Concept ... 23
2.3.1 Secure Boot ... 24
Chapter 3: Linux and Android ... 27
3.1 Linux Kernel ... 27
3.1.1 Introduction ... 27
3.1.2 Kernel Modules ... 29
3.1.3 Memory Management ... 30
3.1.4 Virtual File System ... 35
3.2 Briefly about Android ... 36
3.2.1 Android Initiation ... 38
Chapter 4: Investigation ... 41
4.1 Introduction ... 41
4.2 Kernel Space Security ... 42
4.2.1 The Importance of Kernel Security ... 42
4.2.2 Protection Methods in Kernel Space ... 42
4.3 User Space Security ... 44
4.3.1 Comparison of Integrity Checking in User Space and in Kernel Space ... 45
4.3.2 Protection Methods in User Space ... 46
4.3.3 Analysis of File Reading and Page Error Handling Procedure ... 47
4.3.4 Last Page Handling ... 48
10 | P a g e
4.3.5 Checking Integrity Files List ... 49
Chapter 5: Implementation ... 53
5.1 Kernel Space Security Solution ... 53
5.2 User Space Security Solution ... 55
5.2.1 Where to Put Hash Computations ... 55
5.2.2 Means by which to Check the Integrity List ... 56
Chapter 6: Result ... 59
Chapter 7: Conclusion ... 61
References ... 63
Appendix A: Code Tracing for File Reading Operation ... 65
Appendix B: Code Tracing for Page Fault Handling ... 71
Appendix C: Patch Code of kernel/module.c ... 73
Appendix D: Patch Code of fs/mpage.c ... 75
Appendix E: Patch Code of fs/ext3/inode.c ... 77
11 | P a g e
Table of Figures
F IGURE 1 : T HE WAY TO MAKE A DIGITAL SIGNATURE ... 20
F IGURE 2 : V ERIFYING A SIGNATURE ... 21
F IGURE 3 : P LATFORM ARCHITECTURE ... 24
F IGURE 4 : T HE A NATOMY OF L INUX ... 28
F IGURE 5 : L INUX KERNEL SUB -‐ SYSTEMS ... 28
F IGURE 6 : L OADING MODULES INTO THE L INUX KERNEL ... 30
F IGURE 7 : L OGICAL A DDRESS T RANSLATION ... 31
F IGURE 8 : M EMORY M APPING ... 32
F IGURE 9 : O VERALL S CHEME FOR THE P AGE F AULT H ANDLER ... 34
F IGURE 10 : D IFFERENT LENGTHS OF I/O DATA ... 36
F IGURE 11 : T HE A NDROID PLATFORM LAYERS ... 38
F IGURE 12 : I LLUSTRATION OF A LTERNATIVE 1 ... 42
F IGURE 13 : I LLUSTRATION OF A LTERNATIVE 2 ... 43
F IGURE 14 : P ROGRAM HASH ... 46
F IGURE 15 : P AGE HASHES ... 46
F IGURE 16 : P AGE FAULT HANDLING ... 48
F IGURE 17 : T HE LAST PAGE IS LESS THAN 4 K B, AND THEREFORE FILLED WITH 0 ... 49
F IGURE 18 : INODE IN L INUX MEMORY MANAGEMENT ... 51
F IGURE 19 : R ELATIONSHIP BETWEEN VFS OBJECTS ... 57
12 | P a g e
13 | P a g e
Glossary
Here is a list of acronyms used in this thesis.
API ASCII
Application Program Interface
American Standard Code for Information Interchange DRM
ELF
Digital Right Management Executable and Linkable Format GDB
GPS
The GNU Project Debugger Global Positioning System IMEI
JVM
International Mobile Equipment Identity Java Virtual Machine
LKM MMU
Linux Kernel Module Memory Management Unit MPU Memory Protection Unit
OS Operating System
OSE Operating System Embedded
PC Personal Computer
PGD PTE ROM RSA
Page Global Directory Page Table Entry Read Only Memory
Rivest, Shamir and Adleman SHA Secure Hash Algorithm SMS Short Message Service VFS Virtual file system
VM Virtual Machine
VMA Virtual Memory Addressing
VoIP Voice over Internet Protocol
14 | P a g e
15 | P a g e
Chapter 1: Introduction
Mobile phones have never been more popular. Today mobile communication is flourishing. New, advanced mobile phones and, thus, new mobile services constantly arise. This has led to an awareness of the need to guarantee integrity of data that may be sensitive, and to protect it from user interference.
Android is a new open source mobile platform developed by Google. The popularity of this platform is quickly rising. Many mobile phones manufacturers have already used it in their products. At the time of writing many more are on their way to hit the market.
1.1 Problem Statement
Recently, Android was selected to be integrated in a certain mobile platform by ST- Ericsson. The new project gives rise to a new set of issues regarding security that the company has to deal with. The intent of this thesis is to study the integrity protection on the Linux platform. To avoid of modules/programs on the platform tampered by third parties, their integrity need to be assured.
1.2 Purpose
The aim of this thesis was to investigate the workflows when modules/programs are loaded, and possible integrity protection solutions on ST-Ericsson’s Android based platform. Two different solutions depending on hash storage location in kernel space and non-pages/pages based verification in user space (see Section 4.2.2 and 4.3.2) were analyzed with respect to the lack of security from an integrity perspective. Further, it was studied how these solutions could be extended to solve these problems.
1.3 Method
The selected methodology to conduct the theoretical part of the thesis is a hermeneutic approach, based on the macroscopic view of the mobile platforms by ST-Ericsson. The investigated target is Android kernel code, mainly from Linux kernel code. Due to the limitation of the access to the developed mobile platform, the thesis is conduct under Linux virtual machine with x86 architecture.
According to suggestions from supervisors, the majority of the investigation work went into reading and understanding Linux kernel source code [18], especially in memory management and file system parts, with the help of related books [6], [19], [20] and useful articles on the Internet [10], [26], etc.
For the implementation, the major part was to find the suitable place for the code patch
to the Linux kernel. Aids used were the GNU Project Debugger (GDB) and printing to
16 | P a g e log files. The work in the user mode part was helped by a python-script that generated the correct comparable SHA values.
During the investigation and implementation periods, several supervisors at ST-Ericsson and schools referred in the cover page and acknowledgements part gave plenty of consultation and feedbacks, who have five to more than ten years of experiences in related areas.
The criteria for the evaluation of the prototype is more based on usability and practicability of ST-Ericsson’s future Android platform solutions, including costs and feasibility of the selected solution on real ST-Ericsson’s platforms, also the added execution time and complexity, compared with original Linux/Android kernel.
1.4 Risks, Ethics and Sustainable Development
Risks, in terms of business risks are discussed in Section 2.2. Risks for the end user is that phones are attractive to thieves, or may be hacked for nefarious purposes at all point on the scale from clandestine malware up to malfunction and complete denial of service.
Ethics is usually discussed about the power division between the manufacturer and the end user over a device such as mobile phone. From the side of manufacturer, they prefer to protect the integrity of phones in the full measure. While end users, especially hackers, tend to control what part of software in mobile phones can be modified, without restrictions from manufacturers.
Sustainable development could involve greater energy consumption for more processing overhead, including any positive mechanisms that prevents the user from discarding the device before its expected end of life.
1.5 Limitations
There was no access to a mobile phone with the intended hardware and software setup, so the Linux kernel in user mode built on Linux 2.6.28.8 on a PC was used.
1.6 Audience
The intended audience is anyone who has general security and Linux interest.
1.7 Structure of the Thesis
This report consists of a theory part in Chapters 2 - 3, an investigation part in Chapter
4 and an implementation part in chapter 5. The theory part is written to give the reader
essential background knowledge.
17 | P a g e Chapter 2 (Background) describes basic cryptography theory such as RSA encryption, digital signatures and hashing. It presents potential attacks and includes a short presentation of the ST-Ericsson security concept.
Chapter 3 (Linux and Android) gives an introduction to Linux and Android. Android is a Linux based mobile platform. Therefore it is important to have an understanding of what’s happening on the kernel level, which will help the reader understand what has been done.
Chapter 4 (Investigation) is the backbone of this thesis. This chapter discusses our findings and proposes solutions to the problems presented.
Chapter 5 (Implementation) presents our implementation described in the previous chapter.
Chapter 6 (Result) shows the performance of the different solutions.
Chapter 7 (Conclusion) describes the conclusions of this thesis.
In the rest of this thesis you can find acknowledgment, references, a list of frequently
used acronyms and appendix.
18 | P a g e
19 | P a g e
Chapter 2: Background
Computer security is about protecting information from unauthorized access by unauthorized persons and to keep data available. This consists mainly of four aspects:
• Confidentiality-prevention from unauthorized availability and spreading.
• Availability - keep data available when and where it’s needed.
• Integrity - prevention of unauthorized modification of information.
• Authenticity - assurance that the data was created or sent by the source. (Note the slight difference from integrity, which concentrates on the information).
Viruses, worms and Trojans are all threats that are common on PC plat- forms.
Malicious persons execute these attacks against users and their systems. The attacker is an outside person or group with the intent of retrieving data or just causing havoc etc.
This is quite unlike the attacks that are common on mobile phones. Here the attacker is mainly the user himself that breaches the security of the platform. His intent is to change restrictions and limitations set by the phone manufacturer or the operator.
These types of threats on mobile phones mainly concern integrity and authenticity of software and data.
2.1 Public Key Cryptography
Encryption is the process that converts data, so called plain text, into none-readable form, so called cipher text. The intended recipient of the encrypted data uses decryption to convert the cipher text back into plain text.
Symmetric key encryption uses the same key for both encryption and decryption.
The two involved parties keep this symmetric or secret key secret. This encryption is simple and fast but if anyone else discovers the key other than the two intended parties then that person has the possibility to both access to the data between the two parties and to send new data between them.
In Public-key crypto system (PKC) each party has a pair of keys, one called the
public key and the other called the private key. The former of these keys is published
while the latter is kept secret. This way the need for the two parties to share secret key
information is eliminated. PKC can be used not only for encryption, but also for
authentication (digital signatures) and other various techniques.
20 | P a g e A commonly used algorithm for asymmetric encryption is the RSA algorithm (described in Section 2.1.3). The RSA algorithm is also used for signing, which corresponds to encryption with a private key. Digital Sig- nature and subsequent sections describe how this confirmation process works. Verification of a digital signature will in this case correspond to decryption with the public key.
2.1.1 Signing
Signing is one possible way to establish integrity protection [11]. When signing a document a digital signature is created. A digital signature can be compared with a hand written signature used in the daily life. It confirms that the document originates from a given entity and its content has not been modified, like an unbroken wax stamp did on letters in the older days.
The digital signature of a document is a value that depends on the content of the document. It binds the content of the document to the author and is used in the authentication process. The creation and verification of the digital signature depends on two keys. One of them is a public key that is required for the verification of the digital signature and that can be made available to anybody that wishes to verify the digital signature. The other one is a private key that is kept secret and that only the signer knows and that is used to create the digital signature.
Figure 1 : The way to make a digital signature
The process of creating a digital signature is shown in Figure 1. Instead of encrypting the data itself, a one-way hash of the data is created, called a message digest. This message digest is then encrypted with the private key. The encrypted hash, along with other information, such as the hashing algorithm, is known as a digital signature.
In order to verify the signed document, the data is hashed into a message digest with
the same hash-algorithm used by the signer; message digest A in the Figure 2. Then the
signature is decrypted with the signer’s public key to obtain the message digest B. If the
two message digests are equal, the receiver knows that the signed data has not been
changed and that the author signed the document. An example of commonly used
algorithms for creation of digital signatures is RSA for the encryption part and SHA-256
for the hashing.
21 | P a g e 2.1.2 SHA-256
The SHA-256 algorithm is a hashing function of the Secure Hash Algorithm (SHA) family. It takes any input of any length and creates a message digest of 256 bits. The algorithm only uses fairly cheap operations such as bitwise and, or, xor, addition, and shifts.
Figure 2 : Verifying a signature
A good hash function should fulfil the following basic properties [9]:
• Computationally inexpensive to generate hash for any given in-data.
• It should not be practically feasible to find an in-data message that has a certain given hash value.
• When the in-data message is modified the hash should also be modified
• It should be highly unlikely to find two different in-data messages that will produce the same hash value.
SHA-256 has no known flaws (as its predecessor SHA-1 has) and fulfils the wish list above, and it can thus be considered to be an appropriate cryptographic hash function.
2.1.3 RSA
RSA is an algorithm, named after its inventors (Rivest, Shamir and Adleman) that is suitable for signing as well as encryption. It is based on the problem of factorizing large integer numbers. The RSA algorithm involves three steps: key generation, encryption and decryption.
An RSA crypto system contains three integers to be used in encryption/decryption [1]. The parameter e is called the encryption exponent and d the decryption exponent. The number n is called the modulus. The public key is the set (n, e) and the private key is the set (n, d).
A plain text message P is encrypted to cipher text C with C ≡ Pe(mod n)
The decryption is done similarly by P ≡ Cd(mod n)
22 | P a g e e and d are interchangeable:
P = Cd(mod n) ≡ (P e)d(mod n) ≡ (P d)e(mod n).
The decryption procedure works because the following conditions should hold for the integers:
Cd(mod n) ≡ (Pe)d(mod n) ≡ Ped(mod n) = P.
The following algorithm is used to get an RSA key pair:
1. Generate two large random primes p and q, around the same size.
2. Let n=pq. Use Euler’s phi function and compute φ(n) = (p − 1)(q − 1).
3. Select an integer e, 1 < e < φ(n), such that gcd(e, φ(n)) = 1.
4. With the Euclidean algorithm, calculate the unique integer d, 1 < d < φ(n), such that ed ≡ 1(mod φ(n)).
The public key, used for message encryption and verification of signatures, is (e, n), while the private key, used for message decryption and signature generation, is d. Note that p, q and φ(n) need to be kept secret and can thus be seen as part of the private key.
2.2 Potential Attacks on Mobile Devices
Today even mobile phones are vulnerable to different kinds of malwares, like viruses, worms and trojans, that were previously known to befall only PCs.
For example, a Stealth attack [2] utilizes the mobile phone’s ”send or receive multimedia files”-option to drain its battery by sending unwanted ”junk data” and repeatedly waking up the phone from the standby mode.
Another attack is the Spoofed SMS message [4] that allows an attacker to trick the receiver into visiting a malicious web site, or do something else to harm the phone or steal personal data from it.
The Trojan- SMS Python Flocker [3] utilizes the money transfer service via text messaging.
This trojan sends a message request to the money transfer service to move a small amount of money from the user’s account to an account (most likely) belonging to the hacker. If this trojan spreads well, these streams of small amounts of money can bring great profit to the hacker.
All of the attacks described above are performed by outside attacker(s). They are unpleasant
for the user, but because of Android’s sandboxing (Chapter 3.2) they cannot change anything
on the original platform settings. These attacks are taken care of at a higher level. The rest of
this chapter will focus on the threats to the platform.
23 | P a g e SIMLock
Operators must be able to lock mobile phones to exclusively use their networks by SIMLock [11]. They can lock the phone to a country, different service providers or specific SIM cards.
An attacker may want to be able to use this locked phone in other countries, with other operators or with other SIMcards. The SIMLock capability can prevent this.
International Mobile Equipment Identity
The International Mobile Equipment Identity (IMEI) [11] number uniquely identifies a mobile phone in different networks. This makes it possible to hinder phones that are registered as stolen and blacklisted to be able to connect to the network. It’s important that the attacker should not be able to change the IMEI number and thus be able to use stolen phones again.
Digital Rights Management
Digital Right Management (DRM) [5] covers a number of techniques for restricting the free use and transfer of digital media, which mostly concern video and music files. The attacker wants to have access to free and unlimited files without having the rights to them.
Debranding
Mobile network operators often subsidize and sell mobile phones at a lower price given a subscription with its (potentially annoying) logos, predefined themes, images, sounds, locked WAP profiles, links, etc. The motivation to debrand a phone is often that the branded material and media consumes a considerable amount of memory and clutters the phone, and is not removable while the phone is branded. Debranding removes the mobile operator’s look.
VoIP
If the user has a Voice over Internet Protocol (VoIP) service like Skype on his phone, he has the possibility to make calls via that on a WiFi. It is against the vendor’s interest and therefore they close this service (the user can use Skype but without calling). It’s important that the user/attacker should not be able to change this.
As can be seen, the problems described above can be manifested in different ways and are used for different purposes. It could be re-enabling the use of blacklisted phones, removing vendor content etc, all of which are executed by the user, and not by external attackers.
2.3 ST-Ericsson’s Security Concept
ST-Ericsson tries to protect against attacks described above. The following mechanisms are used in ST-Ericsson platforms [11]:
• Secure boot - verifies the integrity and authenticity of the mobile phone software prior to its execution
• Reprogramming protection - verifies the integrity and authenticity of the mobile phone
software and associated data before programming it into flash memory every time the
software is updated
24 | P a g e
• SW anti-rollback - mechanism to prevent older software versions to be re-installed on the phone to prevent an attacker to exploit bugs in older versions of the software
• SIMLock - ensures the binding of the mobile phone to a particular mobile network or set of networks
• PhoneLock - ST-Ericsson anti-theft feature
• IMEI protection - mechanism to prevent modification of IMEI
The secure boot mechanism is the mechanism that is central for this thesis and is described in more detail below.
2.3.1 Secure Boot
In order to prevent debranding attacks and other attacks described above it is necessary to ensure that unauthorized manipulation of the mobile phone software is detected and that only software from the mobile phone manufacturer or operator or third party approved by the manufacturer or operator is allowed to be executed on the phone. To ensure this ST- Ericsson platforms support a secure boot mechanism where all software is verified prior to its execution.
Figure 3 : Platform architecture Chain of trust
The secure boot mechanism starts with boot ROM code whose integrity is guaranteed by the
fact that it is located in ROM. The ROM code can then load code to be executed, but before
execution it is verified using a verification core located in the ROM. Typically the boot ROM
loads a so called boot loader that is then used to load the software to be executed on the
mobile phone. Several boot loaders exists to boot the software. Each boot loader first verifies
the code that it has loaded before execution is allowed. A chain of trust is created from the
boot ROM in the mobile phone software.
25 | P a g e The boot loaders and mobile phone software are protected using digital signatures. The root public key used for the verification is located in the boot ROM. It is used to protect other public keys used for the verification of the different software components.
Platform architecture
In the mobile platform under study (shown in Figure 3) for this thesis the modem software, that is the software parts related to radio access, is separated from the Android platform and the mobile phone applications. They execute on separate CPUs and they are also signed separately and verified separately by the boot loaders. A memory protection unit (MPU) is used to isolate RAM memory used by the modem software and from the RAM memory used by Android platform and applications.
The modem software is using a real-time operating system called Operating System
Embedded (OSE). The complete modem software is verified prior to execution. OSE was also
used for the application framework and mobile phone applications in previous ST-Ericsson
devices but is now replaced with Linux OS and Android in the platform under study. In the
previous platforms all applications and code belonging to the application framework was
verified prior to execution.
26 | P a g e
27 | P a g e
Chapter 3: Linux and Android
In this chapter an introduction is given to the Linux kernel and the Android platform. This thesis is about integrity protection of the ST-Ericsson platform that uses Android. Android is based on Linux, and thus that needs to be examined. These two components are a very large chunk of the thesis, so this entire chapter is dedicated to them.
3.1 Linux Kernel
The main tasks of the operating system are to provide ”interact[ion] with the hardware components, servicing low-level programmable elements included in the hardware platform [and] provide[ing] an execution environment to the applications that run on the computer system (the so-called user programs).” 1 [6]
3.1.1 Introduction
The Linux kernel is a monolithic kernel. This means that most system processes, such as I/O, memory management, drivers, file system etc are not separate processes, but instead are part of the kernel and runs in privileged mode. This is different from a so-called micro-kernel, where only the very basic operating system (OS) functionality runs as a part of the kernel (scheduling, I/O, etc), and everything else is performed outside the kernel and its privileged space [8].
Linux is split into two spaces with different privileges - user space and kernel space as Figure 4. The kernel space is where Linux performs its OS functionality. Applications are run in the user space with limited access to the kernel space. Only through the so-called system call interface do the user space applications communicate with the kernel. The kernel, in turn, has a number of sub-systems.
1
Bovet, Daniel P. & Cesati, Marco. (2006). Understanding the Linux Kernel. p.8
28 | P a g e The Anatomy of Linux
Figure 4 : The Anatomy of Linux Figure 5 shows the major components [8]:
Figure 5 : Linux kernel sub-systems
29 | P a g e
• System call interface - Provides an interface for user space to communicate with kernel space.
• Process management - Handles execution of processes (threads) and scheduling.
• Virtual file system - Provides a common interface abstraction for file systems.
• Memory management - This is a major part of the kernel, and much attention will be given to it in this chapter.
• Network stack - Provides a variety of networking protocols.
• Architecture - Architecture dependent code that is unique to each different platform that Linux should be able to run on. This is needed for compatibility and performance.
• Device drivers - Most of the code in the Linux kernel are device drivers. These enable I/O to particular hardware devices.
Linux Initiation
The booting process is what fetches and starts the operating system when a phone turns on.
What and how the booting process looks like depends on the environment that is going to be initialized. A description on how the boot loaders fetch the OS in our architecture can be found in Section 2.3.1.
Linux kernel responsibilities
In the kernel all OS processes are handled, including task scheduling, I/O, memory management (such as memory paging and initializing of page tables) and so on. The kernel also executes the init() function, which becomes the first user space process.
The init process
The init() process is the last stage of the boot process, but the first user space process.
This is the parent or grandparent from which all other processes fork. It is responsible for getting the system up and running after booting the kernel by checking file systems, cleaning up /tmp, starting various services, and providing a getty for user login, according to an initial configuration script, /etc/inittab. There are multiple possible run level states for the init process defining what system services are operating, such as halting system, single-user mode, multiuser with networking, etc.
3.1.2 Kernel Modules
Linux is a dynamic kernel. It allows pieces of code to be loaded or unloaded in the form of Linux Kernel Modules (LKM). These modules extend the functionality of the kernel without the need to reboot the system. Some modules are inserted when the kernel is started and others are inserted when the user initiates them. To make it a simple task to manage modules there are a number of useful user tools; (insmod (installing), rmmod (removing), modprobe, etc.).
When writing kernel code, you include files with declarations for functions. The code is
compiled into object files and then linked with the implementation of these declared
30 | P a g e functions. As opposed to this, the modules are not linked after compilation. Modules can thus be seen as object files, or Executable and Linkable Format (ELF) files, whose symbols must be resolved at runtime with the implementations that the kernel provide.
The Linux kernel is the first thing that is loaded into memory.[26] Because of this there is no memory fragmentation and the whole kernel can easily be fitted into continuous memory.
Also, because Linux is responsible for memory management, the concept of paging does not apply to the kernel itself. It simply resides in its piece of memory throughout its lifetime.
With modules, however, the situation has changed. Many processes may be running and memory will be fragmented. When a LKM is loaded it should still occupy a continuous chunk of memory, so the kernel allocates a continuous amount of virtual memory. The whole LKM is loaded into memory and stays there (until unloaded), so paging doesn’t apply for modules either, unlike regular programs where parts are paged in and out of memory throughout their running time.
A system call (sys_init_module()) invokes the module loading. Before the actual loading is performed, the permission level of the caller is verified. If it checks out, the load_module function is called. In this function the module memory is allocated and the ELF that is the module, is linked and loaded into the allocated memory. After the load_module function is completed, the module is placed in a list containing all loaded modules.
Now it’s time to run the initiation code of the newly inserted module. Instead of having a main()-function, like other programs, a module’s entry point is defined by a module_init()-function call. The module is set up in this function and when it’s done it yields in wait of being invoked by the kernel [26]. This process is illustrated in Figure 6.
3.1.3 Memory Management
This thesis and its proposed security enhancements mainly concern the memory management part of Linux. Therefore the memory management system must be dug deeper into.
Figure 6 : Loading modules into the Linux kernel
31 | P a g e Overview
Linux uses different memory addressing modes shown in Figure 7. These are [6]:
Physical address - The addresses used between processor and memory cells on memory chips for physical memory addressing. They are the final addresses in memory address transformation. The addresses are presented as 32-bit or 64-bit unsigned integers.
Logical address - Addresses refer to machine language instructions on data. It is used to specify the address of an instruction or an operand, and consists of a segment and an offset.
They make up the normal address space of the kernel. In most architectures, the difference between logical address and physical address is only a constant offset.
Linear address (Virtual address) - Regular addresses which can be seen by user-space program. Each process has its own virtual address space.
Figure 7 : Logical Address Translation
Logical Address Translation - The Memory Management Unit (MMU) is both responsible for segmentation transformation and paging transformation. Its segmentation unit hardware circuit transforms logical address into linear address; then the paging unit hardware circuit transforms linear address into physical address.
Memory Mapping
There are two types of memory management in operation systems: segmentation and paging.
In segmentation, memory is viewed as a collection of variable-sized segments 2 , rather than linear array of bytes. Different data are located within a segment.
Paging is the memory management technique permitting the physical address space of a process to be non-contiguous. The linear addresses are organized into pages. Actually, the linear addresses are contiguous, and then these groups of contiguous linear addresses in
2
Segments consist of logically related data elements in a defined sequence.
32 | P a g e memory are mapped into corresponding groups of contiguous physical addresses named page frames by the paging unit (described in a later section). By doing so, it avoids external fragmentation. Physical memory is divided into frames. A frame is the place where a logical page can be physically placed. This memory mapping illustrates in Figure 8.
Figure 8 : Memory Mapping
When there is a switch context, the current page table (address) is saved and new one is restored. The OS also has a frame table containing information about all frames, for example whether they are free or which process is using it. Memory that is not allocated to the process cannot be accessed by the process. For efficiency reasons paging is done in hardware.
If heavy and/or many processes are running at the same time, more memory than is available may be needed. For this reason virtual memory is used, which makes it appear as though more memory exist than it actually, physically does.
Linux uses this virtual memory management mechanism, making each process have its own address space with no interference on each other, just like a sandbox. The address space is a 4GB linear virtual space (in 32-bit architectures). The virtual address space is mapped to physical memory by page tables, which are operated by the kernel. Each process has its own page tables set. The users are exposed to the virtual address space, and are not able to see the actual physical memory address space. By using virtual memory management techniques, the operating system is protected (users can not directly access physical memory). Moreover, the user space programs can access address spaces larger than the actual physical memory address space. The virtual address space of each process is divided into two parts - user space and kernel space.
In normal cases, user processes can only access virtual addresses in user space, and not in
kernel space. The process can access the kernel space only when system calls are invoked,
indicating the user process execution to the kernel.
33 | P a g e The Paging Model
The paging unit is responsible for translating linear addresses into physical addresses. The paging unit partitions RAM into page frames of fixed size. Paging mechanism has the following advantages:
• Access permissions defined for the page will be inherited to the group of linear addresses that form the page.
• The size of a page is the same as the size of page frame.
The page table is a data structure responsible for mapping pages into page frames. Those page tables are stored in main memory and are properly initialized by the kernel before the paging unit is enabled.
Linux makes use of the paging unit more than the segmentation unit. All segment descriptors uses the same set of addresses for linear addressing. By doing so, it minimizes the requirements of using the segmentation unit to transform logical addresses to linear addresses.
By making the use of the paging unit more than segmentation unit, Linux facilitates memory management and portability significantly across different hardware architectures.
When a new process is fork()ed, a new set of page tables for the new process is established by the kernel. The addresses, which are referenced in a process in user space, are virtual addresses, and are not necessarily mapped directly to the same physical address. The virtual addresses are passed to the Memory Management Unit, and then the MMU converts them to the proper physical addresses based on the page tables.
Page Fault
What is a Page Fault?
The page fault handler in the Linux kernel is responsible for determining the validity of address/access according to Virtual Memory Addressing (VMA). The general layout of the page fault handler is shown in Figure 9.
There are two kinds of invalid linear addresses that invoke the page fault handler;
programming errors causes one, the other one is caused by missing pages.
34 | P a g e Figure 9 : Overall Scheme for the Page Fault Handler
The page fault handler in the Linux kernel is responsible for identifying and taking actions on several different types of page faults. Every architecture has its specific page fault handling function. The common function name is do_page_fault(). This function provides the information including the fault’s address, whether it is a read or a write fault, whether the page was not found or it was a permission denial error and whether it is a fault from user or kernel space. It is responsible for identifying which type of fault happened and how it should be managed int the specific architecture.
Why Using a Page Fault Mechanism?
Pages occupied by the process in the linear address space are not always necessarily resident in the physical memory. Demand paging is a dynamic memory allocation technique, which delays page frame allocation until the last possible moment. (The process tries to address a page, which is not available in physical memory, and then it causes a Page Fault exception.) Handling a Page Fault
After the page fault exception handler made sure that the exception is a valid page fault in a valid address space, the page data must be fetched. If it is not currently in memory, it’s brought into memory from persistent storage. Because disk access is time consuming, the OS lets other processes run while the disk fetching is active. The fetched page is written into a free physical page and an entry for the virtual page frame number is added to the process page table.
If the process needs to bring a virtual page into physical memory and there are no free
physical pages available, the OS must make room for this page by discarding another page
from the physical memory. This process is called swapping because the pages are swapped
from memory onto the persistent storage.
35 | P a g e Read Ahead Mechanism
When the paging mechanism receives a request from a process to read a page of a certain file, it puts that page in the page cache. It is likely that, in the future, more pages will be requested from the same file, around the same location (spatial and temporal locality). Because of this, it would be beneficial to read larger portions of the file into the cache on the first page request, rather than waiting for the requests from the process.
This is the purpose of the Read-ahead mechanism. When a page is requested it tries to read some ”extra” pages that are likely to be used in the near future by the process.
3.1.4 Virtual File System
All storage devices need some system to describe their data and metadata 3 . This system is known as a file system, and there are many different ways to design and implement such a system. By introducing a Virtual File System (VFS) a common file model can be used as a layer on top of any underlying file system.
The VFS found in Linux primarily consists of a number of object types: superblock, inode, file and dentry [6].
The superblock contains information about a mounted file system. The file object describes an open file used by a process. The dentry is a linked list that is used to describe the directory path to a file.
Files are not only comprised of a file name and data, they are also associated with other information, which is stored in a struct called inode. The inode is not aware of the file name and data of the file. An inode is uniquely identified by its inode number, which ties it to a specific file in the file system. Even if the file name of the file should change, the associated inode will not.
The information stored in the inode is for example; file type, permissions, owner, group, file size, file access, change and modification time, file deletion time, number of links, access control list, etc.
A disk cache allows the kernel to keep some information in RAM that normally is stored on disk. This results in quick access to the cached data when it is needed again, instead of the slow fetching from disk. There are different disk caches such as inode and dentry caches to speed things up. Some inodes will be accessed repeatedly and these inodes will be kept in the inode cache. The dentry cache speeds up the translation from a path name to the inode of the last pathname component.
File Reading Procedure
There is also a page cache. When a user process invokes a read() system call, the VFS tries to fetch the requested page from the page cache. This cache uses address_space structs to define a set of operations that can be used on the pages in the cache. In the event of a cache miss, a new cache entry must be allocated and added to the address_space of the corresponding inode. The function readpage() in address_space is called (through
3
Description of data.
36 | P a g e the function submit_bio()). This sends a request to fetch the page data from disk. When the requested data blocks have been retrieved from the disk, it is stored in the page cache first, and then copied to the user buffer. If the required data needs to be fetched from the block device, the mapping layer determines its physical location on disk.
First, the mapping layer checks the block size of the target file system and calculates the range of the requested data by means of block numbers, which consist of files. Then according to the particular file system, the mapping layer invokes a specific function accessing the file’s inode on disk and determines the location of the requested data on disk by means of logical block numbers and the block count.
The generic block layer starts the read operation on the block device by issuing a series of I/O operations. Each I/O operation comprises a set of continuous blocks on disk. Since the requested data may be non continuous on disk, the generic block layer may do several I/O operations. Each one is symbolized by a bio structure (block I/O), which consists of all information required by the lower layer.
Lower than the generic block layer, the I/O scheduler layer is responsible for organizing the pending I/O data requests in order to sort the data requests, which are stored near each other on the physical disk.
At the bottom layer, the block device drivers make the real data transfer by sending corresponding commands to the disk controller interfaces.
The block device controllers transfer data in term of ”sectors” which is a paradigm also used by the I/O scheduler and the block device drivers. In the upper VFS layer (backed by various file systems), data is organized in ”blocks”, which are the minimal storage units within the file system. For disk caches, it copes with ”pages” of data, which is within a page frame. And the generic block layer recognizes all terms including sectors, blocks, segments, and pages, because it brings together all upper and lower components.
In Figure 10 the different length of these data blocks are illustrated.
Figure 10 : Different lengths of I/O data
3.2 Briefly about Android
Android follows a new wave that offers the users the ability to change a variety of things
ranging from how their device looks and feels to how it functions. Users can replace any
37 | P a g e native application with third-party alternatives, thanks to the fact that the native programs are written using the same APIs and are executed on the same run time as the third-party programs. Good documentation exists to assist (and encourage) developers to write their applications.
Google took the initiative of the Android platform, and the first version saw the light of day in 2008. In short, the Android platform is an open source software stack for mobile devices including an operating system, middleware and key applications.
Android contains the following four layers (as seen in Figure 11 4 ):
Linux kernel
The kernel of Android is the Linux kernel that handles basic core features such as memory management and actual processes. It contains a large number of drivers for the display, camera, Bluetooth, wireless network and other hardware.
Before the Android application framework is launched, the Linux kernel is booted up.
Therefore, it might not come as a surprise that this Linux layer is actually the target of this thesis. It is launched first and controls hardware resources and it thus follows that it is vulnerable to attacks.
Library
On top of the kernel there are a couple of libraries that support graphics, font rendering, text layout engine functionality, databases, security, and (loads of) media support.
In this layer there is also Android Runtime that builds on a Virtual Machine (VM) called Dalvik. It is especially developed for Android, and is not a standard Java Virtual Machine (JVM). Dalvik runs every single program in its own process with a virtual machine of its own, and it uses resources very thrifty. Dalvik is also dependent on the low level Linux functionality.
Application framework
This layer includes programs to fetch and write data from native applications to custom developed applications. It handles windows, views and phone functionalities.
Android does not make a difference between native applications and applications developed by a third party. The result of this is that the developer has access to the camera, GPS, accelerometer, etc. Applications can also handle events like incoming calls and so on.
Application layer
The uppermost layer is the layer that the regular user comes into contact with. There is an e- mail client, a SMS-program, calendar, maps, web browser, contacts, music player, picture gallery, the Android marketplace to download programs, and so on. Every application in this layer is written in the Java language.
As mentioned above Android offers an open architecture where third party vendors or designers can install their own developed application on the system. Normally, new applications can use libraries earlier installed by other programs, but installation of new
4
Source: http://androidteam.googlecode.com/files/Anatomy-Physiology-of-an-Android.pdf. It is licensed under the Creative
Commons Attribution-Share Alike 3.0 Unported license
38 | P a g e applications should not replace, modify or overwrite earlier installed binaries. However, malware does not follow the rules of keeping system libraries and programs ”immune”. It could replace or modify common system binaries (for example ps, ls, netstat in Linux).
3.2.1 Android Initiation
The Android init function
All user space processes needed in the boot will be started from the init process [7]. The order and rules for the processes that are about to be started are fetched from a file called init.rc. The .rc script format is defined by Android.
First the log system is initialized. Then from the init-function all de- vice nodes in /dev are set up and the firmwares are downloaded. Furthermore, a shell is started, adb daemon, service manager, the file system is mounted and Zygote and the Android Java Runtime are launched.
This Java runtime is the most important service since it starts different media services, Bluetooth and so on.
Zygote and Dalvik
From the init-function the Zygote process is launched [7]. The JVM Dalvik process is, in turn, forked from Zygote. It also helps setting up core system dex-files (mmap) and shared heap (in which objects shared by all processes are contained). The system server is then launched by Zygote.
Figure 11 : The Android platform layers
39 | P a g e The system server
Lastly the system server-Java application is started which is in charge of running the other
Java applications needed for the system. It’s the first Java application launched by Zygote. It
starts the core Android services, e.g. ActivityManager, WindowManager, PackageManager
etc. It’s the Android core engine.
40 | P a g e
41 | P a g e
Chapter 4: Investigation
4.1 Introduction
This thesis targets platform security from an integrity and authenticity perspective, i.e. to guarantee the integrity of services on mobile phones. This means that the operating system and existing applications should run without being tampered with.
As mentioned in Section 2.2, on mobile platforms the attacker is most often the user himself.
From a platform security view it’s necessary to ensure that users should not be able to alter the restrictions set by the manufacturer and/or the operator on the new Android platform. In this chapter it will be investigated what needs to be protected and how to protect it.
In the earlier architecture both the modem software and the application software ran on the same operating system, namely OSE. But on the new Android platform the application software runs on Linux. OSE does not have a separate kernel and user space. All processes are handled equally. As opposed to OSE, Linux has separate user and kernel space, where the kernel takes care of all the user processes. ST-Ericsson has a complete, working solution for the old architecture but because of the differences in the new architecture the old solutions need to be reassessed.
Different attacks can occur and they affect different parts of the system (see Section 2.2).
Viruses, worms and trojans usually infect the mobile phones as new installed applications or scripts. Android has a sandboxing framework, which makes such attacks much more contained. Therefore these types of attacks are outside the scope of this thesis. However it must be ensured that the user space itself is protected. Regardless of what happens in the sandbox the platform should remain intact.
The IMEI protection and SIMLock security is located on the modem side. ST-Ericsson already has working solutions for these problems, therefore these threats are also outside of the scope of this thesis.
Debranding and DRM manipulation, for example, are results of attacks on platform integrity, and this is where the concentration will lie on in this thesis. These happen on the application side where the Linux kernel resides.
Since the kernel and applications work on different levels, the protection work is divided into
two parts: for the operating system executed in kernel space and for the programs in user
space.
42 | P a g e
4.2 Kernel Space Security
4.2.1 The Importance of Kernel Security
Considering the Linux kernel to be working between user applications and the hardware, the Linux kernel must be secured in order to secure applications. 5
Moreover, the integrity of applications in user space relies on the assumptions of the kernel’s integrity. If the kernel was cracked, the integrity checking mechanism, which ensures user space applications reliable and secured, will not be guaranteed, even out of the scope completely. Also, the illegal access to the kernel will void all security features on the application side of the mobile platform.
4.2.2 Protection Methods in Kernel Space
As described in The Paging Model in Chapter 3.1.3, due to non-paged design in kernel space, when modules are installed, all code and data will be loaded into memory. As a result, the checking work for the integrity of modules can be done on an entire module at once. The two alternatives for protecting modules in kernel spaces will be discussed below:
Alternative 1:
Linux kernel modules are ELF formatted files, which are used for most executable programs under UNIX systems. Because ELF files include several sections, it is feasible to add a new section to the module file holding integrity information, and let the kernel read it into memory for verification when loading the module [10] (shown in Figure 12).
Figure 12 : Illustration of Alternative 1
5