This article provides an overview of the Firefox OS system security model; that is, it explains how the operating system provides security and enforces permissions.
Terminology
Before diving into the system security model, here are a few key terms you need to understand.
- Web application
- A web application, open web app, moz app, or application is a program written using HTML, JavaScript, and other open Web technologies, running on Firefox OS (or any other platform that supports the same installable app model). All user-facing applications on B2G are web applications. For example, the Dialer is a Web app in Firefox OS. Pages running within the browser are not referred to as Web apps in this context.
- b2g process
- The Firefox OS b2g process is typically referred to as "b2g" or "Gecko". This is, essentially, an application that runs with highly elevated privileges (i.e., runs as root) and controls the access that any web application has to all resources and devices.
- Content process
- This is a child process spawned by the b2g process, and which communicates with the b2g process. It represents a web application. This is a low-privileged process (i.e., run as regular user and has a very limited access and view of/to the operating system). It communicates with the Firefox OS core process using inter-process communication (IPC).
- IPDL
- Intercommunication Protocol Definition Language, see also IPDL.
- AOSP
- Android Open Source Project.
- System call
- An interface to talk between the user-space (processes) and the kernel. There is no other direct way for a user-space process to talk to the kernel.
- DAC, MAC
- Discretionary Access Control (configured by the user) and Mandatory Access Control (enforced by the kernel).
- FOTA
- Firmware Over The Air update system mechanism. This describes full firmware updates, generally sent "over the air", i.e. over a wireless connection to a mobile phone.
- MSU, MAR
- Mozilla System Updater, Mozilla ARchive. Term used to describe Gecko updates, using the same updater mechanism and archive format as Firefox Desktop.
Goals and scope of the Firefox OS system security model
The Firefox OS system security model is designed to:
- Limit and enforce the scope of resources that can be accessed or used by a web application.
- Ensure several layers of security are being correctly used in the operating system.
- Limit and contain the impact of vulnerabilities caused by security bugs, from the Gonk layer.
- Web application permissions and any application related security feature is detailed in the Application Security model.
See the sections below for more detailed explanations of each of these goals, and how they're addressed by Firefox OS.
Enforcing permissions
The Application Security model describes how users grant permissions to applications, either directly or through a trusted third party. These permissions are enforced upon the content process by enforcing any access to resource is realized via an IPC call to the core process.
- The Firefox OS core process,
b2g
, has very high privileges and has access to most hardware devices. - Web applications run in a low-privileged content process and only communicate with the
b2g
core process using IPC, which is implemented using IPDL. - The content process has no operating system-level access to resources.
- Each Web API has one or more associated IPDL protocol declaration file(s) (*.ipdl).
- Firefox OS content processes can only communicate through the IPDL mechanism back to the core process, which will perform actions on behalf of content.
Content process initialization
All web appplications run in a low-rights, separate process: the Firefox OS content process. This process is launched by the b2g
core process when it reaches a special <iframe>
type: <iframe mozapp>. This separates the web application from the rest of the content and is strongly associated to a manifest (see the Application Security model for more information). The content processes are started in the container called an "out of process" container, or an OOP. It is represented by the plugin-container
process and uses similar code to the plugin-container
used by the desktop Firefox.
Risks
- Leak of information when spawning the web application's content process.
- Possibility of accessing operating system resources, and escalating to the same level of privileges as the
b2g
process. - Bypassing the content process initialization.
Implementation
Initialization within the b2g process
In this order:
fork()
setuid(new, different, unused user id|nobody)
(which is an unprivileged user)chrdir('/')
execve('plugin-container')
This ensures the OOP process runs in a separate memory space (new process) and as a low rights user that cannot elevate its privileges to the level of the b2g
process.
File descriptor handling
File descriptors are handled using a whitelist method; a list of permitted file descriptors (FDs) is created and stored in the mFileMap
object. The LaunchApp()
function forcefully closes all FDs not on the whitelist. This is done after fork()
(which is when FDs are copied) but before execve()
(which is when the new app starts running).
Unlike the more traditional method which uses a blacklist (close-on-exec flag: CLOEXEC
), this ensures no FDs are left open; this is, therefore, more reliable.
Content process sandboxing (lowered rights content processes)
Risks
- Memory corruption or logical errors in the Gecko runtime leading to arbitrary code execution.
- Similar faults in the operating system itself (in particular, the kernel) leading to arbitrary code execution.
- Information leakage, read/write access to the file system.
This item has a threat modeling table with the sandbox enabled, in addition to the quick-recap of risks aforementioned.
Scope: the following threats appear if an attacker executes arbitrary code as the content process. In other words, the attacker has already found a vulnerability within gecko.
Threat | Potential impact | Likelihood factor(s) | Proposed mitigation(s) |
---|---|---|---|
Malicious content process exploits exposed kernel vulnerability. "2 steps attack". |
Critical: Full device control. | Low: Content process has a limited amount of system calls available. |
|
Privilege escalation to the parent process. Malicious content process exploits parent process through IPDL. "2 steps attack". |
High: Ability to execute significant number of sensitive system calls (data loss, camera access, network access, etc.). | Medium: Large amount of code in parent process. Large attack surface. Minimal sanitization of data sent through IPDL (it's able to send pointers, for example). |
|
Malicious content process exploits parent process to exploit exposed kernel vulnerability. "3 steps attack". |
Critical: Full device control. |
Low: Requires bug in parent process that can be accessed through IPDL. Requires kernel vulnerability within system call accessible to the parent process (many more system calls are available to the parent process, in comparison to the content process.) |
|
Malicious content, parent process or web application exploits a bug in the device's hardware. "1 and 2 steps attack". |
High: Ability to run privileged operations (such as making calls, sending sms, etc.) up to: Critical: Ability to run code at the hardware level, full device control. |
Low: Requires a communication channel with the hardware, granted through IPDL or system calls, and a hardware bug. |
|
Note: PaX (Protection Against eXecution) is a kernel patch from GrSecurity (docs), which implements both "PaX" and addition protections such as UDEREF and SMAP.
Non-listed vulnerabilities are mitigated by the sandbox itself.
Implementation
Supervisor is not yet implemented.
Note: Content Processes are running the web applications, and are the processes to be sandboxed.
Gecko’s APIs Implementation
APIs exposed via JavaScript in the content process should never attempt to access direct filesystem resources. Instead, these should issue an IPDL call for the resource. This means that any API doing resource access must have a component in the parent process, to access the resource on the behalf of the content process.
Additional care must be taken when implementing the calls. All input must be sanitized by the parent process. The content process cannot be trusted, and the IPDL messages coming from the content process cannot be trusted.
Warning: Any trust given to the content process can and will be used to escape the sandbox.
What is seccomp
Seccomp stands for secure computing mode. There are currently 2 version of seccomp:
-
seccomp
, available in Linux kernel 2.6.12 and above:-
Enabling
seccomp
limits the process’s system calls toread
,write
,sigreturn
, andexit
. -
Uses
prctl()
system call. -
Can be started after process initialization, at an arbitration location.
-
-
seccomp-bpf
, also called seccomp mode filter or mode 2, available in Linux kernel 3.5 and above:-
Same as
seccomp
, but implements BPF to filter system calls. -
Can use a whitelist of system calls & arguments when initialized, instead of hard-coded system calls.
-
More flexible, allows for a “more permissive sandbox”. Useful for slightly weaker sandboxes, and for a smooth transition path to “stricter sandbox”.
-
Adds a flag that prevents the process and child processes for reverting privileges.
-
Note: Due to the increased flexibility it allows, we have decided to use seccomp-bpf
, along with backporting it to any kernel < 3.5. This includes most current Android kernels. A patch is already available and can generally be applied without conflicts (see bug 790923).
Seccomp-bpf performance
seccomp-bpf
impacts performance every time there is a system call. There is no exact benchmark, as the measurement depends on the implementation. We estimate that it may impact performance by up to 1% when a system call is made and seccomp-bpf
is enabled for the running process. This remains to be measured by QA.
Since the number of system calls is greatly reduced in our process model, we also predict the real-world performance impact should be nearly null.
IPDL calls may however add latency and reduce performance, depending on their implementation. It is highly recommended to look at Chromium’s implementation for resource-intensive APIs such as OpenGL calls. In a similar fashion to seccomp-bpf
, if we minimize the number of IPDL calls we will minimize the impacts to performance.
Implementation
seccomp
is enabled in Gecko with --enable-content-sandbox
.
The reporter, which reports denied system calls (if any) is never built by default and is enabled with --enable-content-sandbox-reporter
.
The bulk of the code is in gecko/security/sandbox
. The whitelist itself is stored in gecko/security/sandbox/seccomp_filter.h
.
The whitelist may contain system calls that can be used the compartimentization. Generally, those calls have comments indicating why, and should eventually be removed when the affected code is fixed. Therefore, it's almost never OK to add code that will break the sandbox, then add the call in the whitelist without very careful consideration. In doubt, raise a bug. Most of the time however, this is incorrect, and the resource should instead be controlled, accessed by the b2g process, then passed to the content process if access is granted and/or data is sanitized.
File system hardening
Risks
- Writing, deleting or reading files belonging to another user; this could result in an information leak or unexpected behavior such as privilege escalation.
- Execution of native code through an application vulnerability.
- Vulnerabilities in
setuid
programs (and thus, privilege escalation).
Implementation
The rationale is that only areas that contain user content may be read-write (unless the OS itself requires a new read-write area in the future), and must include nodev
, nosuid
, and noexec
options. The standard filesystem mounts are restricted as follows:
Mount point | File system | Options |
---|---|---|
/ |
rootfs | read-only |
/dev |
tmpfs | read-write, nosuid, noexec, mode=0755 |
/dev/pts |
ptsfs | read-write, nosuid, noexec, mode=0600 |
/proc |
proc | read-write, nosuid, nodev, noexec |
/sys |
sysfs | read-write, nosuid, nodev, noexec |
/cache |
yaffs2 or ext4 | read-write, nosuid, nodev, noexec |
/efs |
yaffs2 or ext4 | read-write, nosuid, nodev, noexec |
/system |
ext4 | read-only, nodev |
/data |
ext4 | read-write, nosuid, nodev, noexec |
/mnt/sdcard |
ext4 or vfat | read-write, nosuid, nodev, noexec, uid=1000, fmask=0702, dmask=0702 |
/acct |
cgroup | read-write, nosuid, nodev, noexec |
/dev/cpuctl |
cgroup | read-write, nosuid, nodev, noexec |
Note: The exact mount points may vary.
Linux DAC
The Linux DAC represents the well-known Linux filesystem permission model.
Note: This is the traditional user/group/others permission model and not the Linux POSIX 1.e ACLs.
- The web application system user has no write access to any file.
- The usage of
setuid
binaries is limited to where necessary. - New content processes are started with a sane
umask
.
Secure system updates
Risks
- Compromised update package data, resulting in an untrusted update package being installed.
- Compromised update check:
- User does not see new updates are available.
- User gets an out of date package as an update, which effectively downgrades the software on the device.
- System state compromised or unknown during the installation of the update; this may (for example) lead to:
- Missing elements during the installation, some of which may be security fixes.
- Security fixes reverted by the compromised system after upgrade.
- Vulnerabilities in the update checking mechanism running on the device.
- Lack of updates or tracking for a software component with a known vulnerability.
Implementation
Subsequent upgrades and patches to the Firefox OS platform are deployed using a secure Mozilla process that ensures the ongoing integrity of the system image on the mobile phone. The update is created by a known, trusted source — usually the device OEM — that is responsible for assembling, building, testing, and digitally signing the update package.
Firmware over the air updates
System updates can involve all or a portion of the Firefox OS stack. If changes to Gonk are included in the update, then FOTA (Firmware Over the Air) is the install process used. FOTA updates can also include any other part of the Firefox OS stack, including device management (FOTA, firmware / drivers), settings management (Firefox OS settings), security updates, Gaia, Gecko, and other patches.
MSU/MAR updates
Updates that do not involve Gonk can be done using the Mozilla System Update Utility. Firefox OS uses the same update framework, processes, and Mozilla ARchive (MAR) format (used for update packages) as the Firefox Desktop product.
Update service
Note: The update service may be provided by the OEM.
A built-in update service on the mobile phone periodically checks for system updates. Once a system package becomes available and is detected by the update service, the user is prompted to confirm installation. Before updates are installed on the mobile device, the device storage is checked for sufficient space to apply the update, and the distribution is verified for:
- Update origin (verify the source location protocol:domain:port of the system update and manifest).
- File integrity (cryptographic hash checksums).
- Code signature (certificate check against a trusted root).
The following security measures are used during the update process:
- Mozilla recommends and expects that updates are fetched over an SSL connection with a trusted certificate.
- Strong cryptographic verification is required before installing a firmware package.
- The complete update must be downloaded in a specific and secure location before the update process begins.
- The system must be in a secure state when the update process starts, with no web applications running.
- The keys must be stored in a secure location on the device.
Rigorous checks are in place to ensure that the update is applied properly to the mobile phone.
Note: For more information on platform updates, read Creating and applying Firefox OS update packages.