Commit graph

52 commits

Author SHA1 Message Date
Tom Cherry
c5cf85db23 init: don't log in expand_props directly
It's better to pass the error message to the caller to determine how
best to print the error.

Test: build
Change-Id: Id8857c459df2f26c031650166609608d20e4d051
2019-08-01 10:34:58 -07:00
Vic Yang
92c236e41b init: Refactor selinux.h/cpp
This change factors out functions that handle selabels from
selinux.h/cpp into selabel.h/cpp.  This allows util.cpp to be used by
the upcoming native zygote without a bunch of define flags that are
required for selinux.cpp.

Bug: 133443795
Test: Build and boot cuttlefish.
Change-Id: Ie238a96c6407c6698a605dd8803c1727abfaae7b
2019-05-29 15:09:39 -07:00
Tom Cherry
59656fb377 init: dump stack when aborting
Dump init stacks when aborting either due to LOG(FATAL) or in
userdebug/eng builds due to signals, including signals from
sanitizers.

Doesn't work for static first stage init yet, b/133450393 tracks
that.

Also, ensure that LOG(FATAL) in child processes calls abort() in all
stages of init, not just 2nd stage init.

Bug: 131747478
Test: abort init in various ways and see stacks
Test: hang or crash in backtrace handler and see child reboot
Change-Id: Ib53b5d3e7e814244203f875de016ada9900dfce8
2019-05-29 08:58:29 -07:00
Mark Salyzyn
44505ecdd9 init: move "started at" environment var names to headers
Move "FIRST_STAGE_STARTED_AT" to env_first_stage_started_at variable
in first_stage_init.h.  Move "SELINUX_STARTED_AT" to
env_selinux_started_at variable in selinux.h.

Test: build
Bug: 124491153
Bug: 129780532
Change-Id: I512d1835dcee5a3d034ac453b27b0709eed23cff
2019-05-08 13:50:21 -07:00
Mark Salyzyn
10377df9f8 init: ro.boottime.init.first_stage
Add a property ro.boottime.init.first_stage to provide us a
first stage init duration from start to exec completed in
nanoseconds.

For consistency, report nanoseconds duration for
ro.boottime.init.selinux as well instead of milliseconds.
Now also report consistently from start to exec completed
instead of just the selinux load time.

SideEffects: ro.boottime.init.selinux is reported to TRON and
             may alarm with the millionfold increase in precision.
             ro.boottime.init is now also consistent with ns
             precision.

Test: inspect
Bug: 124491153
Bug: 129780532
Change-Id: Iff4f1a3a1ab7ff0a309c278724c92da0832b9a69
2019-05-08 16:07:10 +00:00
Jeff Vander Stoep
0ac51cfc01 Load selinux compat file if it exists
This addresses Treble backwards compat issues introduced in
aosp/793958 and aosp/783669.

Bug: 122874820
Test: build/flash blueline with pi-dev vendor and generic_ab system
    images.
Test: adb pull /sys/fs/selinux/policy;
    sesearch policy --allowx -s vendordomain -t dev_type

Change-Id: I9123aa02cf4bf07d72d1ea086dde0d1cf1b30db4
2019-05-02 14:25:06 -07:00
Bowgo Tsai
30afda71c0 Copying debug ramdisk files to /debug_ramdisk/*
In previous implementation, userdebug sepoilcy and property files are
loaded from the system.img. This CL changes this to:

  - first-stage init copies userdebug files from ramdisk to /debug_ramisk/*
  - second-stage init loads files from /debug_ramdisk/*.

Note: same as before, the above can only be triggered, if the device
is UNLOCKED

With this, we don't have to put userdebug related files into the USER
system.img.

Bug: 126493225
Test: boot device with a ramdisk with /force_debuggable, checks related
      files are loaded
Change-Id: I63f5f846e82ba78427062bf7615c26173878d8f3
2019-04-19 09:56:14 +08:00
Jeffrey Vander Stoep
e21d07fbab Merge "selinux: use the policy version defined in sepolicy" 2019-03-19 21:44:59 +00:00
Bowgo Tsai
1dacd42ae1 Allow overriding ro.debuggable to 1 on USER builds
When init found "/force_debuggable" in the first-stage ramdisk, it will
do the following if the device is unlocked:
  1. load /system/etc/adb_debug.prop (with ro.debuggable=1)
  2 .load userdebug_plat_sepolicy.cil instead of original plat_sepolicy.cil from
    /system/etc/selinux/.

This make it possible to run VTS on a USER build GSI, by using a special
ramdisk containing "/force_debuggable".

Bug: 126493225
Test: unlock a USER build device, check 'adb root' can work
Change-Id: I9b4317bac1ce92f2c0baa67c83d4b12deba62c92
2019-03-15 06:12:00 +08:00
Jiyong Park
4ba548d845 mount /apex during first_stage init
/apex is not mounted via init.rc but directly by the first_stage init
before the mount namespaces are configured.

This allows us to change the propagation type for /apex mount point to
private to isolate APEX activatesions across post- and pre-apexd
processes.

Bug: 125549215
Test: m; device boots to the UI

Change-Id: I10e056cd30d64cb702b6c237acd8dab326162884
2019-03-04 16:22:41 +09:00
Jeff Vander Stoep
724eda5503 selinux: use the policy version defined in sepolicy
In the current setup, init uses the highest policy version supported
by the kernel, instead of the policy version defined in policy. This
results in inconsistency between precompiled (version 30) and
on-device compiled policy (version 30 or 31). Make these consistent.

Bug: 124499219
Test: build and boot a device. Try both precompiled and on-device
compiled policy.

Change-Id: I0ce181916f43db17244c4d80f5cf5a91bbb58d3a
2019-02-25 10:47:29 -08:00
Tri Vo
c8137f93f7 selinux: account for /product hash
We need to be able to tell if /product was updated independently
/system.  Otherwise, the device might accidentally load the
precompiled_policy after a /product sepolicy update.

Bug: 119305624
Test: boot aosp_taimen, precompiled policy is loaded
Test: If either of these hashes
/system/etc/selinux/plat_sepolicy_and_mapping.sha256
/product/etc/selinux/product_sepolicy_and_mapping.sha256
are removed, then init falls back to compiling sepolicy at boot time.
Change-Id: I3d658335cf66bcb7123109de701309039b1ae5ba
2019-01-23 09:23:22 -08:00
Tri Vo
7ca2c565b0 Merge "init: load /product selinux mapping file" 2019-01-22 18:49:21 +00:00
Tao Bao
a68d8c9ea3 init: Remove the obsolete restorecon for /sbin files.
These files, including their building rules, have been removed in favor
of their dynamically linked versions; we no longer need to explicitly
restorecon the actual files either, for the same reason as in commit
05f96a2561. When doing normal boot, these
files come from system.img, which have been labeled at build time; when
booting recovery, they don't need dedicated labels to be functional.

Test: Build and boot crosshatch.
Test: Factory reset under recovery on taimen (mke2fs).
Test: Factory reset under recovery on crosshatch (make_f2fs).
Change-Id: Icbcd24aad8be1e7f4ba7d379acd5855d256ae106
2019-01-17 14:52:29 -08:00
Tri Vo
503f1852ba init: load /product selinux mapping file
/system/etc/selinux/mapping/V.v.cil is being split into /system and
/product parts.

Change init to account for /product/etc/selinux/mapping/V.v.cil mapping
file when merging SELinux policies.

Bug: 119305624
Test: boot taimen
Test: "cnd" type is declared in /vendor; "dataservice_app" type is
declared in /product. This permission is preserved
"allow cnd dataservice_app:binder { transfer call };"
Change-Id: I65995a75041044ae71c148d655a70c5efd3b84cc
2019-01-16 12:54:32 -08:00
Tri Vo
05f96a2561 init: don't restorecon root sepolicy files
Removing restorecon on root sepolicy files because:
1. Under normal boot the files are properly labeled when creating the
image. Restorecon'ing them successfully would require "adb remount".
2. These restorecon's are not required for recovery to function.

Fixes: 122535196
Test: boot blueline
Change-Id: I20b127e950b16535d4bfa9fd4e626e11228925e7
2019-01-10 00:50:43 +00:00
Tri Vo
d3518cf4c8 init: support loading /product/etc/selinux/product_sepolicy.cil
Bug: 119305624
Test: boot aosp_taimen with product_sepolicy.cil
Change-Id: I2124275de7ffc0058c48f5d5ef16644d5d39da3b
2018-12-14 15:45:16 -08:00
Tom Cherry
7bfea3d59c init: clean up the 1st/2nd stage init split
The first split of 1st/2nd stage init went a bit overboard, since it
split these even in the case of the recovery image and system-as-root,
which don't actually need the split.  This change simplifies this a
bit:

system-as-root and recovery have a single combined /system/bin/init
and a symlink from /init to it.

non-system-as-root has a separate first stage init at /init on the
first stage ramdisk and a combined /system/bin/init on system.img.

Two particular benefits from this:
1) Removal of the rsync of TARGET_RAMDISK_OUT to the recovery image
2) Decrease of overall space on the recovery image since it won't have
   a statically linked first stage init

This also unified the various entry points of init to depend entirely
on the arguments passed to it, instead of the hybrid of arguments and
environment variable used previously.

Bug: 80395578
Test: boot both system-as-root and non-system-as-root
Change-Id: Ic2f29b6f56b7defc80eaa0e7cd0c9107e978816f
2018-11-12 16:08:19 -08:00
Tom Cherry
132615b803 Merge "Move watchdogd out of init" 2018-08-03 19:28:14 +00:00
Tom Cherry
40acb379cd Move watchdogd out of init
We're moving past a world where static executables are needed,
including watchdogd, so treat this like any other executable and place
it in /system/bin.

Bug: 73660730
Test: watchdogd still runs
Change-Id: I1f7508fd55dce6e9ee72a6ab7a085011a76c0053
2018-08-02 12:25:58 -07:00
Tom Cherry
81ae07509d init: run fsck for early mount partitions
Bug: 111883560
Test: fsck runs successfully during early mount
Change-Id: I19bcd2610f87f5331f94c228fcbec8f9379fc5e8
2018-07-31 13:58:17 -07:00
Tom Cherry
74069d1734 init: clean up logging initialization
Clean up a few mistakes in logging initialization

1) Only init needs to clear stdout/stderr/stdin, so remove this from
   ueventd, watchdogd, and subcontext init
2) Only init should reboot due to FATAL errors. This was true even
   before this change due to getpid() checks, but there's no reason to
   not just use the DefaultAborter for other processes.
3) It's probably a mistake for FATAL logs in init to try to gracefully
   shutdown the system, so simply call RebootSystem() here.
4) Lastly, remove log.cpp since it's not actually shared code anymore

Test: build
Change-Id: Ic8c323393dc7ee98ed6bb9691361b51d0d915267
2018-07-20 15:30:14 -07:00
Logan Chien
837b2a4c24 init: Use sepolicy version instead
This commit uses vendor sepolicy file version (defined in
`/vendor/etc/selinux/plat_sepolicy_vers.txt`) to determine whether the
source context should be set as `u:r:vendor_init:s0`.

Before this commit, the criterion was `ro.vndk.version` >= 28.  However,
the check in `property_service.cpp` will always be true because
`ro.vndk.version` hasn't been loaded from `/vendor/default.prop`.

Furthermore, under some circumstances, `ro.vndk.version` may be
different from `plat_sepolicy_vers.txt` (e.g. O-MR1 vendor does not
define `ro.vndk.version`).

Bug: 78605339  # high-level bug to combine O-MR1 and P GSI
Bug: 79135481  # the usage of `ro.vndk.version` in init
Test: vts-tradefed run vts -m VtsTrebleVintfTest  # tetheroffload
Change-Id: Ied46e9346b4ca7931aa4dcf1c9dbc11de0e12d93
2018-05-04 15:21:01 +08:00
Bowgo Tsai
36cf353ffb sepolicy: renames nonplat_* to vendor_*
Also fallbacks to nonplat_* if it doesn't exists.

Bug: 64240127
Bug: 70279378
Test: boot bullhead and sailfish
Change-Id: I372b42a3c559ae0f9602163699eaef4df148467b
2018-01-09 18:47:12 +08:00
Jaegeuk Kim
899ad558cd fastboot/fs_mgr/init: add sload_f2fs
Change-Id: Iab1e4037cbb835aba97f941c8840b8971caf38e7
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
2017-12-06 22:40:08 -08:00
Bowgo Tsai
43da9ee604 Merge "init/selinux: renames nonplat_declaration.cil to plat_pub_versioned.cil"
am: d06a0c035b

Change-Id: I9d5f5c441dc3669417787f69116f6e332807d337
2017-12-01 05:06:43 +00:00
Bowgo Tsai
069ab5bd1a init/selinux: renames nonplat_declaration.cil to plat_pub_versioned.cil
The content of nonplat_declaration.cil in /vendor is a versioned public
sepolicy exported from ${AOSP}/system/sepolicy/public. Renames it to
better reflect the fact.

Bug: 64240127
Test: boot sailfish normally without odm
Test: boot another device having odm
Change-Id: I654f5bbde2f2d666a2a5c7ed8561ccd93c983a6e
2017-11-29 18:13:10 +08:00
Xin Li
23e27db576 Merge commit 'a63ccea6abc7ea02e2d98e41c80793ca97237bd3' from
oc-mr1-dev-plus-aosp into stage-aosp-master

Change-Id: Ia33311cd1fd26dfaea59a69317b306fb91203c40
Merged-In: I03d06b10807e8a313c9654c2e1db36bfb59e3f99
2017-11-14 13:19:45 -08:00
Nick Kralevich
3d118e72dd Don't use TEMP_FAILURE_RETRY on close()
See https://lkml.org/lkml/2005/9/10/129 for details.

Bug: 20501816
Test: code compiles and boots with no obvious problems.
Change-Id: I5a9c470156d498852cfd81fbd59ddcf267309e73
2017-10-24 10:46:34 -07:00
Jeffrey Vander Stoep
e04a7757ac Merge "Allow redeclaring typeattributes" am: f8bc6cee3f am: ceb5dea905
am: b7559e571b

Change-Id: I093f8be7b4f8c810d4ffefab5461687bdc883ac7
2017-10-08 04:18:13 +00:00
Jeff Vander Stoep
5e9ba3c50b Allow redeclaring typeattributes
Allows partners to add a new attribute definition to their public
policy without causing a compatibility failure with the AOSP system
image.

Bug: 67092827
Bug: 37915794
Test: build and boot aosp_sailfish with a new type declared in public
    policy.

Change-Id: I3899065affb6806ae9080e1a7dfa5a6f368370f0
2017-10-06 17:04:28 -07:00
kaichieh
84fb623f64 Merge "Add odm sepolicy support to selinux.cpp" am: f899548cdb am: 1aecf73b43
am: a4d04e1f26

Change-Id: Iba1cb0c66fffe8d59bf9056bd9a6e6932518d4e4
2017-09-04 05:12:57 +00:00
kaichieh
eef4cd7d08 Add odm sepolicy support to selinux.cpp
init: support loading odm sepolicy

Currently init merges two sepolicy cil files:
    - /system/etc/selinux/plat_sepolicy.cil
    - /vendor/etc/selinux/nonplat_sepolicy.cil

This change replaces nonplat_sepolicy.cil with the following two files:
    - /vendor/etc/selinux/declaration/nonplat_declaration.cil
    - /vendor/etc/selinux/vender_sepolicy.cil

And support merging another default (but optional):
    - /odm/etc/selinux/odm_sepolicy.cil.

Bug: 64240127
Test: boot sailfish normally without odm.cil
Test: boot another device having odm.cil
Change-Id: I0b7f8c656c73ddb0fd46f2af3c625d7c81566f2f
2017-09-01 18:13:29 +08:00
Tom Cherry
c3e9c2adca Merge changes I316c13e3,I4d99744d,Id9614b72,I7c98a0b7 am: a78b5b300b am: e0db940e52
am: ab6b6e2c3c

Change-Id: I8a3894121ff73bea73192f918252dd3db3bcbf53
2017-08-23 22:55:43 +00:00
Tom Cherry
6de21f1112 init: cleanup environment handling
Init keep its own copy of the environment that it uses for execve when
starting services.  This is unnecessary however as libc already has
functions that mutate the environment and the environment that init
uses is clean for starting services.  This change removes init's copy
of the environment and uses the libc functions instead.

This also makes small clean-up to the way the Service class stores
service specific environment variables.

Test: boot bullhead
Change-Id: I7c98a0b7aac9fa8f195ae33bd6a7515bb56faf78
2017-08-23 10:09:21 -07:00
Andreas Huber
9c0804bbb0 Fix use-after-free of stack-allocated temporary string. am: c41b838baa am: a5efddda90
am: dbd2ac1202

Change-Id: I3afd60abcb45a9ae39388630edb274b8eca3ecc1
2017-08-21 17:46:28 +00:00
Andreas Huber
c41b838baa Fix use-after-free of stack-allocated temporary string.
Bug: 64848081
Test: built and successfully booted again
Merged-In: I93c899249bf2cc5ab8d880c0eaff471518e73121

Change-Id: I93c899249bf2cc5ab8d880c0eaff471518e73121
2017-08-21 09:44:56 -07:00
Tom Cherry
0be5ecf56a Merge "init: replace panic() with LOG(FATAL)" am: 57a89f3ba0 am: ce2325895f am: 0ae159a920
am: 18966c55e9

Change-Id: I460028050b79b9e759996485124561e33c8cc3fa
2017-08-18 16:15:58 +00:00
Tom Cherry
ce2325895f Merge "init: replace panic() with LOG(FATAL)"
am: 57a89f3ba0

Change-Id: Ib00187f9296ea8afd2bd323a87e290e7424a864e
2017-08-18 15:58:26 +00:00
Tom Cherry
57a89f3ba0 Merge "init: replace panic() with LOG(FATAL)" 2017-08-18 15:49:46 +00:00
Tom Cherry
2e9773a30a Merge "init: fix copy/paste mistake" am: f85404521e am: ad42b33eaa am: c3398d9e87
am: 3cbfff1615

Change-Id: I736005a89352b5e313960355d4bd28bdbeb18476
2017-08-18 02:36:28 +00:00
Tom Cherry
ad42b33eaa Merge "init: fix copy/paste mistake"
am: f85404521e

Change-Id: Id7382a959f5a22e4f4897ad593ea7202aae95c19
2017-08-18 01:55:43 +00:00
Tom Cherry
d8db7ab80d init: replace panic() with LOG(FATAL)
Test: boot bullhead
Test: Introduce LOG(FATAL) at various points of init and ensure that
      it reboots to the bootloader successfully
Test: Introduce LOG(FATAL) during DoReboot() and ensure that it reboots
      instead of recursing infinitely
Test: Ensure that fatal signals reboot to bootloader

Change-Id: I409005b6fab379df2d635e3e33d2df48a1a97df3
2017-08-17 18:16:51 -07:00
Tom Cherry
94f3bcdbc1 init: fix copy/paste mistake
Test: boot bullhead
Change-Id: I0fedb48a9684e21a27a1d260b84cb49a1038ce3f
2017-08-17 16:52:10 -07:00
Tom Cherry
db640d87cd Merge changes I7f00c5f0,Idc18f331,I1e7d3a88
am: 334929b525

Change-Id: If6526adf256c1e5958d5aa6135d9e7efd11cf1cf
2017-08-14 22:52:34 +00:00
Tom Cherry
11a3aeeae3 init: introduce Result<T> for return values and error handling
init tries to propagate error information up to build context before
logging errors.  This is a good thing, however too often init has the
overly verbose paradigm for error handling, below:

bool CalculateResult(const T& input, U* output, std::string* err)

bool CalculateAndUseResult(const T& input, std::string* err) {
  U output;
  std::string calculate_result_err;
  if (!CalculateResult(input, &output, &calculate_result_err)) {
    *err = "CalculateResult " + input + " failed: " +
      calculate_result_err;
      return false;
  }
  UseResult(output);
  return true;
}

Even more common are functions that return only true/false but also
require passing a std::string* err in order to see the error message.

This change introduces a Result<T> that is use to either hold a
successful return value of type T or to hold an error message as a
std::string.  If the functional only returns success or a failure with
an error message, Result<Success> may be used.  The classes Error and
ErrnoError are used to indicate a failed Result<T>.

A successful Result<T> is constructed implicitly from any type that
can be implicitly converted to T or from the constructor arguments for
T.  This allows you to return a type T directly from a function that
returns Result<T>.

Error and ErrnoError are used to construct a Result<T> has
failed. Each of these classes take an ostream as an input and are
implicitly cast to a Result<T> containing that failure.  ErrnoError()
additionally appends ": " + strerror(errno) to the end of  the failure
string to aid in interacting with C APIs.

The end result is that the above code snippet is turned into the much
clearer example below:

Result<U> CalculateResult(const T& input);

Result<Success> CalculateAndUseResult(const T& input) {
  auto output = CalculateResult(input);
  if (!output) {
    return Error() << "CalculateResult " << input << " failed: "
                   << output.error();
  }
  UseResult(*output);
  return Success();
}

This change also makes this conversion for some of the util.cpp
functions that used the old paradigm.

Test: boot bullhead, init unit tests
Merged-In: I1e7d3a8820a79362245041251057fbeed2f7979b
Change-Id: I1e7d3a8820a79362245041251057fbeed2f7979b
2017-08-14 14:07:30 -07:00
Tom Cherry
009c13083a Merge changes I7f00c5f0,Idc18f331,I1e7d3a88 into oc-dr1-dev-plus-aosp
am: 08adddec07

Change-Id: I582ced4450761fe8540e5f11ead33c561717b1de
2017-08-14 20:31:41 +00:00
Tom Cherry
c317009410 init: split security functions out of init.cpp
This change splits out the selinux initialization and supporting
functionality into selinux.cpp and splits the security related
initialization of the rng, etc to security.cpp.  It also provides
additional documentation for SEPolicy loading as this has been
requested by some teams.

It additionally cleans up sehandle and sehandle_prop.  The former is
static within selinux.cpp and new wrapper functions are created around
selabel_lookup*() to better serve the users.  The latter is moved to
property_service.cpp as it is isolated to that file for its usage.

Test: boot bullhead
Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60
Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60
(cherry picked from commit 9afb86b25d8675927cb37c86119a7ecf19f74819)
2017-08-14 11:07:27 -07:00
Tom Cherry
62ca663475 init: introduce Result<T> for return values and error handling
init tries to propagate error information up to build context before
logging errors.  This is a good thing, however too often init has the
overly verbose paradigm for error handling, below:

bool CalculateResult(const T& input, U* output, std::string* err)

bool CalculateAndUseResult(const T& input, std::string* err) {
  U output;
  std::string calculate_result_err;
  if (!CalculateResult(input, &output, &calculate_result_err)) {
    *err = "CalculateResult " + input + " failed: " +
      calculate_result_err;
      return false;
  }
  UseResult(output);
  return true;
}

Even more common are functions that return only true/false but also
require passing a std::string* err in order to see the error message.

This change introduces a Result<T> that is use to either hold a
successful return value of type T or to hold an error message as a
std::string.  If the functional only returns success or a failure with
an error message, Result<Success> may be used.  The classes Error and
ErrnoError are used to indicate a failed Result<T>.

A successful Result<T> is constructed implicitly from any type that
can be implicitly converted to T or from the constructor arguments for
T.  This allows you to return a type T directly from a function that
returns Result<T>.

Error and ErrnoError are used to construct a Result<T> has
failed. Each of these classes take an ostream as an input and are
implicitly cast to a Result<T> containing that failure.  ErrnoError()
additionally appends ": " + strerror(errno) to the end of  the failure
string to aid in interacting with C APIs.

The end result is that the above code snippet is turned into the much
clearer example below:

Result<U> CalculateResult(const T& input);

Result<Success> CalculateAndUseResult(const T& input) {
  auto output = CalculateResult(input);
  if (!output) {
    return Error() << "CalculateResult " << input << " failed: "
                   << output.error();
  }
  UseResult(*output);
  return Success();
}

This change also makes this conversion for some of the util.cpp
functions that used the old paradigm.

Test: boot bullhead, init unit tests
Change-Id: I1e7d3a8820a79362245041251057fbeed2f7979b
2017-08-14 10:26:57 -07:00
Tom Cherry
0c8d6d2730 init: split security functions out of init.cpp
This change splits out the selinux initialization and supporting
functionality into selinux.cpp and splits the security related
initialization of the rng, etc to security.cpp.  It also provides
additional documentation for SEPolicy loading as this has been
requested by some teams.

It additionally cleans up sehandle and sehandle_prop.  The former is
static within selinux.cpp and new wrapper functions are created around
selabel_lookup*() to better serve the users.  The latter is moved to
property_service.cpp as it is isolated to that file for its usage.

Test: boot bullhead
Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60
Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60
2017-08-14 09:40:01 -07:00