User:Tedd/B2G Supervisor

From MozillaWiki
Jump to: navigation, search

In FirefoxOS (Boot2Gecko), the main system process, b2g, is running as root user. b2g is exposed to a lot of input that is controlled by a potential attacker, which makes it a good target to escalate to root privileges. Therefore it is desired to have b2g run with non-root privileges (see b2g-no-root). This document should give an overview about potential threats, status of the supervisor development and future work.

Threats

One of the main questions is, what do we gain by running b2g as non-root user? Here some examples of potential threats of a malicious root user:

  • load kernel modules (install a rootkit)
  • overclock CPU (physically break the phone)
  • modifications that survive a factory reset (for example Cerberus for Android)
  • larger attack surface on the kernel

Design

IPC

The supervisor process doesn't share an IPDL connection with b2g, like the app processes and b2g do. Instead it relies on a custom IPC implementation, which suits the needed functionality. For the acutal socket operations, recvmsg() and sendmsg() are used, this gives us the option to transfer file descriptors across the IPC channel.

Message

Messages that are being send across the channel need to have the following format:

#define SV_MESSAGE_MAX_FDS 0x7
...
struct SvMessage {
  struct SvMessageHeader header;
  int32_t fds[SV_MESSAGE_MAX_FDS];
  char data[0];
};

The header is defined as follows:

struct SvMessageHeader {
  uint32_t magic;
  uint32_t id;
  uint32_t nfds;
  uint32_t size;
  uint32_t type;
  uint32_t opt;
};

Message fields:

  • header: message header, described below
  • fds: integer array that contains up to SV_MESSAGE_MAX_FDS file descriptors
  • data: optional sized field that contains additional data of any kind

Header fields:

  • magic: static value to identify the beginning of a message
  • id: random value, used to acknowledge a packet by including it in the response message
  • nfds: number of file descriptors that come with the message
  • size: size of the data in the actual message
  • type: describes the message kind (more detail later on)
  • opt: optional field, is specific to the type

types and opts

Currently the following types along with opt values are supported:

type opt comment
SV_TYPE_ERROR SV_ERROR_OK the operation was completed without any error
SV_ERROR_MISSING the message is missing some data for the operation
SV_ERROR_INVALID the message contains invalid data (e.g. wrong number of file descriptors)
SV_ERROR_FAILED the operation has failed
SV_ERROR_DENIED the operation is not allowed
SV_ERROR_MEMORY the operations requires to much memory
SV_TYPE_CMD SV_CMD_WIFI executes a command regarding wifi
SV_CMD_REBOOT executes reboot(...) with whitelisted parameters
SV_CMD_SETPRIO executes setpriority() of given PID/TID, excludes supervisor PID

Whitelists

List of currently maintained whitelists in the supervisor

Reboot

Allowd values for the reboot() argument

Value Notes
RB_AUTOBOOT for restarting the system
RB_POWER_OFF for shutting down the system

Blacklists

List of currently maintained blacklists in the supervisor

setpriority

prohibited PID values for setpriority()

Value Notes
0 would change priority of supervisor
`pidof supervisor` same as pid = 0

Development

b2g has been running with root privileges from the beginning, so developers didn't pay much attention to what they do that requires root permissions. Currently, we drop the privileges of b2g to system and see what doesn't work.

Changes

This section will cover the changes that have been made so far, to the system as well as to the code.

Filesystem

Some directories or files require system as their owner, so that b2g can access them:

Path Owner Group Source code location
/data/b2g/ system root B2G/system/core/include/private/android_filesystem_config.h
/data/local/ system root B2G/system/core/rootdir/init.rc
/system/b2g/ system root B2G/system/core/include/private/android_filesystem_config.h

This has been added to the filesystem

Path Permission Owner Group Source code
/system/b2g/supervisor -r-x------ root root B2G/system/core/include/private/android_filesystem_config.h

Code

Some things can only be changed during runtime by the program. We need to call setgroups() before lowering our privileges to system, since on Android we can't add the system user to groups by default. After we added ourself to the right groups, we need to call setresuid() to drop all our privileges to system (this includes the EUID, if it isn't dropped as well, we could recover root privileges). We need to add ourself to the following groups (defined in: B2G/system/core/include/private/android_filesystem_config.h).

Group Reason Note
AID_SYSTEM allows access to filesystem with system as group
AID_MOUNT allows access to /dev/socket/vold (volume deamon) check for potential risk
AID_INPUT allows access to /dev/input/* check for potential risk
AID_SHELL allows access to files by this group
AID_INET allows calling socket()
AID_NET_BT allows creating bluetooth sockets
AID_NET_ADMIN allows calling setsockopt()

Changes to existing code might also be necessary, all changes are maintained in the following list, along with the reason.

Location Change Reason Comment
marionettecomponent.js change 666 to 6666 bind() on port < 1024 requires root port 666 is an arbitrary choice, free to change

Remoting

This section covers all the operations that need to be remoted, and ideally the code location that needs to be changed to do so.

Opreation Code locations
PowerOff() LinuxPower.cpp
Reboot() LinuxPower.cpp
setpriority() GonkHal.cpp
wifi_load_driver() WifiUtils.cpp
wifi_unload_driver() WifiUtils.cpp
wifi_start_supplicant() WifiUtils.cpp
wifi_stop_supplicant() WifiUtils.cpp
wifi_connect_to_supplicant() WifiUtils.cpp
wifi_command() WifiUtils.cpp

Current

What is currently worked on will be listed here:

Priority What Notes Status
high find more broken code identify operations that have to be remoted
high sync messaging implement sync messages, so that child (b2g) can wait for a response from parent (supervisor) done
high nuwa needs permission to setuid/setgid root is required for setuid/setgid, currently we have nuwa run as root to do so done
high fix WIFI it seems everything in WifiUtils.cpp needs to be remoted
high update software find out how updating works and remote root operations
med fix RIL logcat shows a bunch of permission denied for RIL connect()
med remote PowerOff() done
med remote Reboot() b2g crashes with SIGSEGV
med proper logging implement proper logging, not just with #ifdef DEBUG
low remote setpriority() done
low fix screenshot save probably can't write to the filesystem, but don't know yet what the problem is
low /proc/self permissions usually a process is allowed to make some changes to itself (e.g. /proc/self/oom_score_adj), but the permissions are wrong since we drop the privileges without a re-exec

Notes

This sections contains dumps from raw logs to keep track of the important informations that might come in handy

[pid  2389] open("/sys/module/printk/parameters/time", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2389/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2401] unlink("/dev/socket/keystore") = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2504/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2504/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2504/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] <... open resumed> )        = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)

[pid  2389] open("/sys/class/leds/lcd-backlight/brightness", O_RDWR|O_LARGEFILE) = 104
[pid  2389] write(104, "2", 1)          = -1 EACCES (Permission denied)

[pid  2389] open("/proc/2525/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2698/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] <... open resumed> )        = -1 EACCES (Permission denied)
[pid  2723] open("/data/dontpanic", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/bluetoothd", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/bluetooth", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/keystore", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/wifi", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/dhcp", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/audio", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/misc/location", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/property", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/radio", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] open("/data/drm", O_RDONLY|O_LARGEFILE|O_DIRECTORY) = -1 EACCES (Permission denied)
[pid  2723] stat64("/data/system/wpa_supplicant", 0x471ef5f0) = -1 EACCES (Permission denied)
[pid  2723] stat64("/data/system/wpa_supplicant", 0x471ef5f0) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2504/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2525/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
[pid  2389] open("/proc/2525/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)

[pid  2389] open("/sys/class/power_supply/battery/capacity", O_RDONLY|O_LARGEFILE) = 196
[pid  2389] write(196, "2", 1)          = -1 EACCES (Permission denied)

[pid  2389] open("/proc/2454/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)

[pid  2743] open("/sys/class/timed_output/vibrator/enable", O_RDWR|O_LARGEFILE) = 130
[pid  2389] write(130, "2", 1)          = -1 EACCES (Permission denied)

[pid  2389] open("/proc/2525/oom_score_adj", O_WRONLY|O_LARGEFILE) = -1 EACCES (Permission denied)

permissions

ls -la /data/misc
drwxrwx--- audio    audio             2014-08-11 19:43 audio
drwxrwx--- bluetooth bluetooth          2014-08-11 19:43 bluetooth
drwxrwx--- bluetooth bluetooth          2014-08-11 19:43 bluetoothd
drwxrwx--- dhcp     dhcp              2014-08-11 19:43 dhcp
drwxrwx--- system   gps               2014-08-11 19:43 gpsone_d
drwxrwx--x system   system            2014-08-11 19:43 keychain
drwx------ keystore keystore          2014-08-11 19:43 keystore
drwxrwx--- gps      gps               2014-08-11 19:43 location
drwxrwx--- gps      system            2014-08-11 19:43 quipc
drwxrwxr-x system   system            2014-08-11 19:43 sensors
drwx------ system   system            2014-08-11 19:43 systemkeys
drwxrwx--- system   vpn               2014-08-11 19:43 vpn
drwxrwx--- wifi     wifi              2014-08-20 22:52 wifi

ls -la /data/
...
drwx------ root     root              2014-08-20 23:12 property
drwxr-x--- root     log               2014-08-11 19:43 dontpanic
drwxrwx--- drm      drm               2014-08-11 19:43 drm
drwxrws--- radio    radio             2014-08-11 19:43 radio
...

ls -la /data/system/wpa_supplicant
lrwxrwxrwx root     root              2014-08-11 19:43 wpa_supplicant -> /data/misc/wifi/wpa_supplicant

ls -la /data/misc/wifi/wpa_supplicant
srwxrwx--- wifi     wifi              2014-08-20 23:11 wlan0

ls -la /data/property
-rw------- root     root            5 2014-08-11 19:43 persist.dsds.enabled
-rw------- root     root            1 2014-08-11 19:43 persist.radio.adb_log_on
-rw------- root     root            1 2014-08-20 23:12 persist.radio.net_pref_0
-rw------- root     root            1 2014-08-11 19:43 persist.radio.nv_sms_utc
-rw------- root     root            1 2014-08-11 19:43 persist.radio.sma_voice_3gpp
-rw------- root     root            9 2014-08-20 22:39 persist.sys.timezone
-rw------- root     root           16 2014-08-11 19:43 persist.sys.usb.config