Merge "fastbootd: Fix USB transport data is repeated every 256K"
diff --git a/NOTICE b/NOTICE
index 152be20..8e8a91c 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,324 +1,16 @@
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for the Android-specific code. ==
- =========================================================================
+Copyright (C) 2017 The Android Open Source Project
-Android Code
-Copyright 2005-2008 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This product includes software developed as part of
-The Android Open Source Project (http://source.android.com).
+ http://www.apache.org/licenses/LICENSE-2.0
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for Apache Commons code. ==
- =========================================================================
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
-Apache Commons
-Copyright 1999-2006 The Apache Software Foundation
+-------------------------------------------------------------------
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for Jakarta Commons Logging. ==
- =========================================================================
-
-Jakarta Commons Logging (JCL)
-Copyright 2005,2006 The Apache Software Foundation.
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for the Nuance code. ==
- =========================================================================
-
-These files are Copyright 2007 Nuance Communications, but released under
-the Apache2 License.
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for the Media Codecs code. ==
- =========================================================================
-
-Media Codecs
-These files are Copyright 1998 - 2009 PacketVideo, but released under
-the Apache2 License.
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for the TagSoup code. ==
- =========================================================================
-
-This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
-
-TagSoup is licensed under the Apache License,
-Version 2.0. You may obtain a copy of this license at
-http://www.apache.org/licenses/LICENSE-2.0 . You may also have
-additional legal rights not granted by this license.
-
-TagSoup is distributed in the hope that it will be useful, but
-unless required by applicable law or agreed to in writing, TagSoup
-is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-OF ANY KIND, either express or implied; not even the implied warranty
-of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for Additional Codecs code. ==
- =========================================================================
-
-Additional Codecs
-These files are Copyright 2003-2010 VisualOn, but released under
-the Apache2 License.
-
- =========================================================================
- == NOTICE file corresponding to the section 4 d of ==
- == the Apache License, Version 2.0, ==
- == in this case for the Audio Effects code. ==
- =========================================================================
-
-Audio Effects
-These files are Copyright (C) 2004-2010 NXP Software and
-Copyright (C) 2010 The Android Open Source Project, but released under
-the Apache2 License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
-
-
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-Unicode Data Files include all data files under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/,
-and http://www.unicode.org/cldr/data/ . Unicode Software includes any
-source code published in the Unicode Standard or under the directories
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
-http://www.unicode.org/cldr/data/.
-
-NOTICE TO USER: Carefully read the following legal agreement. BY
-DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA
-FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY
-ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF
-THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY,
-DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright © 1991-2008 Unicode, Inc. All rights reserved. Distributed
-under the Terms of Use in http://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Unicode data files and any associated documentation (the
-"Data Files") or Unicode software and any associated documentation (the
-"Software") to deal in the Data Files or Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, and/or sell copies of the Data Files or Software,
-and to permit persons to whom the Data Files or Software are furnished to
-do so, provided that (a) the above copyright notice(s) and this permission
-notice appear with all copies of the Data Files or Software, (b) both the
-above copyright notice(s) and this permission notice appear in associated
-documentation, and (c) there is clear notice in each modified Data File
-or in the Software as well as in the documentation associated with the
-Data File(s) or Software that the data or software has been modified.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
-OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in these Data Files or Software without prior written
-authorization of the copyright holder.
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 52cff94..da7fca1 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -52,10 +52,6 @@
"name": "memunreachable_unit_test"
},
{
- "name": "memunreachable_unit_test",
- "host": true
- },
- {
"name": "memunreachable_binder_test"
},
{
diff --git a/bootstat/Android.bp b/bootstat/Android.bp
index edff26d..545a06f 100644
--- a/bootstat/Android.bp
+++ b/bootstat/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstat_lib_src_files = [
"boot_event_record_store.cpp",
]
@@ -93,4 +97,7 @@
"boot_event_record_store_test.cpp",
"testrunner.cpp",
],
+ test_options: {
+ unit_test: true,
+ },
}
diff --git a/bootstat/AndroidTest.xml b/bootstat/AndroidTest.xml
deleted file mode 100644
index f3783fa..0000000
--- a/bootstat/AndroidTest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Config for bootstat_tests">
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="bootstat_tests->/data/local/tmp/bootstat_tests" />
- </target_preparer>
- <option name="test-suite-tag" value="apct" />
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="bootstat_tests" />
- </test>
-</configuration>
\ No newline at end of file
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 8979e9a..ee1ae31 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1322,6 +1322,8 @@
// Record the total time from device startup to boot complete, regardless of
// encryption state.
+ // Note: we are recording seconds here even though the field in statsd atom specifies
+ // milliseconds.
boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime_s.count());
RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
diff --git a/cli-test/Android.bp b/cli-test/Android.bp
index 37a1d1b..59618b4 100644
--- a/cli-test/Android.bp
+++ b/cli-test/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "cli-test",
host_supported: true,
diff --git a/code_coverage/Android.bp b/code_coverage/Android.bp
index b51c802..2cb1617 100644
--- a/code_coverage/Android.bp
+++ b/code_coverage/Android.bp
@@ -1,4 +1,8 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
prebuilt_etc {
name: "code_coverage.policy",
sub_dir: "seccomp_policy",
diff --git a/cpio/Android.bp b/cpio/Android.bp
index baa0319..16af079 100644
--- a/cpio/Android.bp
+++ b/cpio/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2005 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary_host {
name: "mkbootfs",
srcs: ["mkbootfs.c"],
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 53f85bf..fb274ec 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -1,3 +1,31 @@
+package {
+ default_applicable_licenses: ["system_core_debuggerd_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "system_core_debuggerd_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
cc_defaults {
name: "debuggerd_defaults",
cflags: [
diff --git a/debuggerd/crasher/Android.bp b/debuggerd/crasher/Android.bp
index 61c5395..7975a3a 100644
--- a/debuggerd/crasher/Android.bp
+++ b/debuggerd/crasher/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "crasher-defaults",
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 65820bd..9e9557f 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <dirent.h>
#include <err.h>
#include <fcntl.h>
#include <malloc.h>
@@ -373,11 +374,11 @@
ConsumeFd(std::move(output_fd), &result);
#if defined(__aarch64__)
- ASSERT_MATCH(result, "memory near x0");
+ ASSERT_MATCH(result, "memory near x0 \\(\\[anon:");
#elif defined(__arm__)
- ASSERT_MATCH(result, "memory near r0");
+ ASSERT_MATCH(result, "memory near r0 \\(\\[anon:");
#elif defined(__x86_64__)
- ASSERT_MATCH(result, "memory near rdi");
+ ASSERT_MATCH(result, "memory near rdi \\(\\[anon:");
#else
ASSERT_TRUE(false) << "unsupported architecture";
#endif
@@ -1444,9 +1445,16 @@
std::this_thread::sleep_for(100ms);
// Find the tombstone.
- std::optional<int> tombstone_index;
- for (int i = 0; i < 50; ++i) {
- std::string path = android::base::StringPrintf("/data/tombstones/tombstone_%02d", i);
+ std::optional<std::string> tombstone_file;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_h(opendir("/data/tombstones"), closedir);
+ ASSERT_TRUE(dir_h != nullptr);
+ std::regex tombstone_re("tombstone_\\d+");
+ dirent* entry;
+ while ((entry = readdir(dir_h.get())) != nullptr) {
+ if (!std::regex_match(entry->d_name, tombstone_re)) {
+ continue;
+ }
+ std::string path = android::base::StringPrintf("/data/tombstones/%s", entry->d_name);
struct stat st;
if (TEMP_FAILURE_RETRY(stat(path.c_str(), &st)) != 0) {
@@ -1454,14 +1462,13 @@
}
if (st.st_dev == text_st.st_dev && st.st_ino == text_st.st_ino) {
- tombstone_index = i;
+ tombstone_file = path;
break;
}
}
- ASSERT_TRUE(tombstone_index);
- std::string proto_path =
- android::base::StringPrintf("/data/tombstones/tombstone_%02d.pb", *tombstone_index);
+ ASSERT_TRUE(tombstone_file);
+ std::string proto_path = tombstone_file.value() + ".pb";
struct stat proto_fd_st;
struct stat proto_file_st;
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index b42d70c..7fe8f82 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -379,7 +379,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_uaf_exact) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::USE_AFTER_FREE, &meta);
crash_data.SetCrashAddress(0x1000);
@@ -396,7 +396,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_double_free) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::DOUBLE_FREE, &meta);
crash_data.SetCrashAddress(0x1000);
@@ -413,7 +413,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_overflow) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_OVERFLOW, &meta);
crash_data.SetCrashAddress(0x1025);
@@ -432,7 +432,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_underflow) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::BUFFER_UNDERFLOW, &meta);
crash_data.SetCrashAddress(0xffe);
@@ -451,7 +451,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_inside) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta);
crash_data.SetCrashAddress(0x1001);
@@ -470,7 +470,7 @@
TEST_F(TombstoneTest, gwp_asan_cause_invalid_free_outside) {
gwp_asan::AllocationMetadata meta;
meta.Addr = 0x1000;
- meta.Size = 32;
+ meta.RequestedSize = 32;
GwpAsanCrashDataTest crash_data(gwp_asan::Error::INVALID_FREE, &meta);
crash_data.SetCrashAddress(0x1021);
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 185bd6e..4f75ff1 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -42,6 +42,7 @@
#include <android-base/unique_fd.h>
#include <android/log.h>
#include <async_safe/log.h>
+#include <bionic/macros.h>
#include <log/log.h>
#include <log/log_read.h>
#include <log/logprint.h>
@@ -362,7 +363,7 @@
regs->IterateRegisters([log, maps, memory](const char* reg_name, uint64_t reg_value) {
std::string label{"memory near "s + reg_name};
if (maps) {
- unwindstack::MapInfo* map_info = maps->Find(reg_value);
+ unwindstack::MapInfo* map_info = maps->Find(untag_address(reg_value));
if (map_info != nullptr && !map_info->name.empty()) {
label += " (" + map_info->name + ")";
}
@@ -592,7 +593,6 @@
}
ProcessInfo process_info;
- unique_fd attr_fd(open("/proc/self/attr/current", O_RDONLY | O_CLOEXEC));
process_info.abort_msg_address = abort_msg_address;
engrave_tombstone(unique_fd(dup(tombstone_fd)), unique_fd(dup(proto_fd)), &unwinder, threads, tid,
process_info, nullptr, nullptr);
@@ -619,7 +619,7 @@
log.tfd = output_fd.get();
log.amfd_data = amfd_data;
- bool translate_proto = GetBoolProperty("debug.debuggerd.translate_proto_to_text", false);
+ bool translate_proto = GetBoolProperty("debug.debuggerd.translate_proto_to_text", true);
if (translate_proto) {
tombstone_proto_to_text(tombstone, [&log](const std::string& line, bool should_log) {
_LOG(&log, should_log ? logtype::HEADER : logtype::LOGS, "%s\n", line.c_str());
diff --git a/debuggerd/libdebuggerd/tombstone_proto.cpp b/debuggerd/libdebuggerd/tombstone_proto.cpp
index bb3c7ea..23ca070 100644
--- a/debuggerd/libdebuggerd/tombstone_proto.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto.cpp
@@ -39,6 +39,7 @@
#include <android-base/unique_fd.h>
#include <android/log.h>
+#include <bionic/macros.h>
#include <log/log.h>
#include <log/log_read.h>
#include <log/logprint.h>
@@ -233,7 +234,7 @@
dump.set_register_name(name);
- unwindstack::MapInfo* map_info = maps->Find(value);
+ unwindstack::MapInfo* map_info = maps->Find(untag_address(value));
if (map_info) {
dump.set_mapping_name(map_info->name);
}
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index f941990..6f13ed4 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -391,8 +391,10 @@
case SIGSYS:
switch (si->si_code) {
case SYS_SECCOMP: return "SYS_SECCOMP";
+ case SYS_USER_DISPATCH:
+ return "SYS_USER_DISPATCH";
}
- static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code");
+ static_assert(NSIGSYS == SYS_USER_DISPATCH, "missing SYS_* si_code");
break;
case SIGTRAP:
switch (si->si_code) {
diff --git a/debuggerd/proto/Android.bp b/debuggerd/proto/Android.bp
index bb82f03..b78224b 100644
--- a/debuggerd/proto/Android.bp
+++ b/debuggerd/proto/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
filegroup {
name: "libtombstone_proto-src",
srcs: ["tombstone.proto"],
diff --git a/debuggerd/proto/tombstone.proto b/debuggerd/proto/tombstone.proto
index 38a06f4..2c7156b 100644
--- a/debuggerd/proto/tombstone.proto
+++ b/debuggerd/proto/tombstone.proto
@@ -3,6 +3,9 @@
option java_package = "com.android.server.os";
option java_outer_classname = "TombstoneProtos";
+// NOTE TO OEMS:
+// If you add custom fields to this proto, do not use numbers in the reserved range.
+
message Tombstone {
Architecture arch = 1;
string build_fingerprint = 2;
@@ -24,6 +27,8 @@
repeated MemoryMapping memory_mappings = 17;
repeated LogBuffer log_buffers = 18;
repeated FD open_fds = 19;
+
+ reserved 20 to 999;
}
enum Architecture {
@@ -31,6 +36,8 @@
ARM64 = 1;
X86 = 2;
X86_64 = 3;
+
+ reserved 4 to 999;
}
message Signal {
@@ -46,15 +53,21 @@
bool has_fault_address = 8;
uint64 fault_address = 9;
+
+ reserved 10 to 999;
}
message Cause {
string human_readable = 1;
+
+ reserved 2 to 999;
}
message Register {
string name = 1;
uint64 u64 = 2;
+
+ reserved 3 to 999;
}
message Thread {
@@ -63,6 +76,8 @@
repeated Register registers = 3;
repeated BacktraceFrame current_backtrace = 4;
repeated MemoryDump memory_dump = 5;
+
+ reserved 6 to 999;
}
message BacktraceFrame {
@@ -76,6 +91,8 @@
string file_name = 6;
uint64 file_map_offset = 7;
string build_id = 8;
+
+ reserved 9 to 999;
}
message MemoryDump {
@@ -83,6 +100,8 @@
string mapping_name = 2;
uint64 begin_address = 3;
bytes memory = 4;
+
+ reserved 5 to 999;
}
message MemoryMapping {
@@ -97,6 +116,8 @@
string mapping_name = 7;
string build_id = 8;
uint64 load_bias = 9;
+
+ reserved 10 to 999;
}
message FD {
@@ -104,11 +125,15 @@
string path = 2;
string owner = 3;
uint64 tag = 4;
+
+ reserved 5 to 999;
}
message LogBuffer {
string name = 1;
repeated LogMessage logs = 2;
+
+ reserved 3 to 999;
}
message LogMessage {
@@ -118,4 +143,6 @@
uint32 priority = 4;
string tag = 5;
string message = 6;
+
+ reserved 7 to 999;
}
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 3e0c47c..bc2d33d 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -143,13 +143,13 @@
CrashArtifact result;
std::optional<std::string> path;
- result.fd.reset(openat(dir_fd_, ".", O_WRONLY | O_APPEND | O_TMPFILE | O_CLOEXEC, 0640));
+ result.fd.reset(openat(dir_fd_, ".", O_WRONLY | O_APPEND | O_TMPFILE | O_CLOEXEC, 0660));
if (result.fd == -1) {
// We might not have O_TMPFILE. Try creating with an arbitrary filename instead.
static size_t counter = 0;
std::string tmp_filename = StringPrintf(".temporary%zu", counter++);
result.fd.reset(openat(dir_fd_, tmp_filename.c_str(),
- O_WRONLY | O_APPEND | O_CREAT | O_TRUNC | O_CLOEXEC, 0640));
+ O_WRONLY | O_APPEND | O_CREAT | O_TRUNC | O_CLOEXEC, 0660));
if (result.fd == -1) {
PLOG(FATAL) << "failed to create temporary tombstone in " << dir_path_;
}
@@ -408,12 +408,21 @@
}
}
-static bool link_fd(borrowed_fd fd, borrowed_fd dirfd, const std::string& path) {
- std::string fd_path = StringPrintf("/proc/self/fd/%d", fd.get());
+static bool rename_tombstone_fd(borrowed_fd fd, borrowed_fd dirfd, const std::string& path) {
+ // Always try to unlink the tombstone file.
+ // linkat doesn't let us replace a file, so we need to unlink before linking
+ // our results onto disk, and if we fail for some reason, we should delete
+ // stale tombstones to avoid confusing inconsistency.
+ int rc = unlinkat(dirfd.get(), path.c_str(), 0);
+ if (rc != 0 && errno != ENOENT) {
+ PLOG(ERROR) << "failed to unlink tombstone at " << path;
+ return false;
+ }
- int rc = linkat(AT_FDCWD, fd_path.c_str(), dirfd.get(), path.c_str(), AT_SYMLINK_FOLLOW);
+ std::string fd_path = StringPrintf("/proc/self/fd/%d", fd.get());
+ rc = linkat(AT_FDCWD, fd_path.c_str(), dirfd.get(), path.c_str(), AT_SYMLINK_FOLLOW);
if (rc != 0) {
- PLOG(ERROR) << "failed to link file descriptor";
+ PLOG(ERROR) << "failed to link tombstone at " << path;
return false;
}
return true;
@@ -446,36 +455,22 @@
CrashArtifactPaths paths = queue->get_next_artifact_paths();
- // Always try to unlink the tombstone file.
- // linkat doesn't let us replace a file, so we need to unlink before linking
- // our results onto disk, and if we fail for some reason, we should delete
- // stale tombstones to avoid confusing inconsistency.
- rc = unlinkat(queue->dir_fd().get(), paths.text.c_str(), 0);
- if (rc != 0 && errno != ENOENT) {
- PLOG(ERROR) << "failed to unlink tombstone at " << paths.text;
- return;
- }
-
- if (crash->output.text.fd != -1) {
- if (!link_fd(crash->output.text.fd, queue->dir_fd(), paths.text)) {
- LOG(ERROR) << "failed to link tombstone";
+ if (rename_tombstone_fd(crash->output.text.fd, queue->dir_fd(), paths.text)) {
+ if (crash->crash_type == kDebuggerdJavaBacktrace) {
+ LOG(ERROR) << "Traces for pid " << crash->crash_pid << " written to: " << paths.text;
} else {
- if (crash->crash_type == kDebuggerdJavaBacktrace) {
- LOG(ERROR) << "Traces for pid " << crash->crash_pid << " written to: " << paths.text;
- } else {
- // NOTE: Several tools parse this log message to figure out where the
- // tombstone associated with a given native crash was written. Any changes
- // to this message must be carefully considered.
- LOG(ERROR) << "Tombstone written to: " << paths.text;
- }
+ // NOTE: Several tools parse this log message to figure out where the
+ // tombstone associated with a given native crash was written. Any changes
+ // to this message must be carefully considered.
+ LOG(ERROR) << "Tombstone written to: " << paths.text;
}
}
if (crash->output.proto && crash->output.proto->fd != -1) {
if (!paths.proto) {
LOG(ERROR) << "missing path for proto tombstone";
- } else if (!link_fd(crash->output.proto->fd, queue->dir_fd(), *paths.proto)) {
- LOG(ERROR) << "failed to link proto tombstone";
+ } else {
+ rename_tombstone_fd(crash->output.proto->fd, queue->dir_fd(), *paths.proto);
}
}
@@ -509,7 +504,7 @@
}
int main(int, char* []) {
- umask(0137);
+ umask(0117);
// Don't try to connect to ourselves if we crash.
struct sigaction action = {};
diff --git a/diagnose_usb/Android.bp b/diagnose_usb/Android.bp
index 93d13bd..cb79ffe 100644
--- a/diagnose_usb/Android.bp
+++ b/diagnose_usb/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libdiagnose_usb",
cflags: ["-Wall", "-Wextra", "-Werror"],
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 85a19e5..a1f1c17 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -14,6 +14,34 @@
// This is required because no Android.bp can include a library defined in an
// Android.mk. Eventually should kill libfastboot (defined in Android.mk)
+package {
+ default_applicable_licenses: ["system_core_fastboot_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "system_core_fastboot_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
cc_library_host_static {
name: "libfastboot2",
@@ -243,6 +271,12 @@
generated_headers: ["platform_tools_version"],
+ tidy_flags: [
+ // DO NOT add quotes around header-filter flag regex argument,
+ // because build/soong will add quotes around the whole flag.
+ "-header-filter=(system/core/fastboot/|development/host/windows/usb/api/)",
+ ],
+
target: {
windows: {
srcs: ["usb_windows.cpp"],
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 2b2a0bf..b2b6a9e 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -659,7 +659,7 @@
return device->WriteFail("No snapshot merge is in progress");
}
- auto sm = SnapshotManager::NewForFirstStageMount();
+ auto sm = SnapshotManager::New();
if (!sm) {
return device->WriteFail("Unable to create SnapshotManager");
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index f7edf8e..38be934 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1103,6 +1103,7 @@
static std::string get_current_slot() {
std::string current_slot;
if (fb->GetVar("current-slot", ¤t_slot) != fastboot::SUCCESS) return "";
+ if (current_slot[0] == '_') current_slot.erase(0, 1);
return current_slot;
}
@@ -1950,6 +1951,7 @@
if (slot_override == "") {
std::string current_slot;
if (fb->GetVar("current-slot", ¤t_slot) == fastboot::SUCCESS) {
+ if (current_slot[0] == '_') current_slot.erase(0, 1);
next_active = verify_slot(current_slot, false);
} else {
wants_set_active = false;
diff --git a/fastboot/fuzzy_fastboot/Android.bp b/fastboot/fuzzy_fastboot/Android.bp
index aa449b2..159c314 100644
--- a/fastboot/fuzzy_fastboot/Android.bp
+++ b/fastboot/fuzzy_fastboot/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_fastboot_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ default_applicable_licenses: ["system_core_fastboot_license"],
+}
+
cc_test_host {
name: "fuzzy_fastboot",
compile_multilib: "first",
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 96cc5c8..5356b00 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -14,6 +14,34 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["system_core_fs_mgr_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "system_core_fs_mgr_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-MIT",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
cc_defaults {
name: "fs_mgr_defaults",
sanitize: {
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index abece4d..75d1e0d 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -26,7 +26,7 @@
#include "fs_mgr_priv.h"
-std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline) {
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) {
static constexpr char quote = '"';
std::vector<std::pair<std::string, std::string>> result;
@@ -60,12 +60,50 @@
return result;
}
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig(
+ const std::string& cmdline) {
+ static constexpr char quote = '"';
+
+ std::vector<std::pair<std::string, std::string>> result;
+ for (auto& line : android::base::Split(cmdline, "\n")) {
+ line.erase(std::remove(line.begin(), line.end(), quote), line.end());
+ auto equal_sign = line.find('=');
+ if (equal_sign == line.npos) {
+ if (!line.empty()) {
+ // no difference between <key> and <key>=
+ result.emplace_back(std::move(line), "");
+ }
+ } else {
+ result.emplace_back(android::base::Trim(line.substr(0, equal_sign)),
+ android::base::Trim(line.substr(equal_sign + 1)));
+ }
+ }
+
+ return result;
+}
+
+bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig,
+ const std::string& android_key, std::string* out_val) {
+ FS_MGR_CHECK(out_val != nullptr);
+
+ const std::string bootconfig_key("androidboot." + android_key);
+ for (const auto& [key, value] : fs_mgr_parse_proc_bootconfig(bootconfig)) {
+ if (key == bootconfig_key) {
+ *out_val = value;
+ return true;
+ }
+ }
+
+ *out_val = "";
+ return false;
+}
+
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& android_key,
std::string* out_val) {
FS_MGR_CHECK(out_val != nullptr);
const std::string cmdline_key("androidboot." + android_key);
- for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) {
+ for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) {
if (key == cmdline_key) {
*out_val = value;
return true;
@@ -76,6 +114,17 @@
return false;
}
+// Tries to get the given boot config value from bootconfig.
+// Returns true if successfully found, false otherwise.
+bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val) {
+ std::string bootconfig;
+ if (!android::base::ReadFileToString("/proc/bootconfig", &bootconfig)) return false;
+ if (!bootconfig.empty() && bootconfig.back() == '\n') {
+ bootconfig.pop_back();
+ }
+ return fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, out_val);
+}
+
// Tries to get the given boot config value from kernel cmdline.
// Returns true if successfully found, false otherwise.
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) {
@@ -110,6 +159,11 @@
return true;
}
+ // next, check if we have the property in bootconfig
+ if (fs_mgr_get_boot_config_from_bootconfig_source(key, out_val)) {
+ return true;
+ }
+
// finally, fallback to kernel cmdline, properties may not be ready yet
if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) {
return true;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 42459ec..785a8e0 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -412,7 +412,8 @@
if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
- for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
+ for (const char* prefix :
+ {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab.", "/first_stage_ramdisk/fstab."}) {
std::string fstab_path = prefix + suffix;
if (access(fstab_path.c_str(), F_OK) == 0) {
return fstab_path;
@@ -854,7 +855,7 @@
if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
std::set<std::string> boot_devices;
const std::string cmdline_key = "androidboot.boot_device";
- for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) {
+ for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) {
if (key == cmdline_key) {
boot_devices.emplace(value);
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 388c296..1134f14 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -125,10 +125,38 @@
namespace {
+bool fs_mgr_in_recovery() {
+ // Check the existence of recovery binary instead of using the compile time
+ // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
+ // defined, albeit not in recovery. More details: system/core/init/README.md
+ return fs_mgr_access("/system/bin/recovery");
+}
+
+bool fs_mgr_is_dsu_running() {
+ // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
+ // never called in recovery, the return value of android::gsi::IsGsiRunning()
+ // is not well-defined. In this case, just return false as being in recovery
+ // implies not running a DSU system.
+ if (fs_mgr_in_recovery()) return false;
+ auto saved_errno = errno;
+ auto ret = android::gsi::IsGsiRunning();
+ errno = saved_errno;
+ return ret;
+}
+
// list of acceptable overlayfs backing storage
const auto kScratchMountPoint = "/mnt/scratch"s;
const auto kCacheMountPoint = "/cache"s;
-const std::vector<const std::string> kOverlayMountPoints = {kScratchMountPoint, kCacheMountPoint};
+
+std::vector<const std::string> OverlayMountPoints() {
+ // Never fallback to legacy cache mount point if within a DSU system,
+ // because running a DSU system implies the device supports dynamic
+ // partitions, which means legacy cache mustn't be used.
+ if (fs_mgr_is_dsu_running()) {
+ return {kScratchMountPoint};
+ }
+ return {kScratchMountPoint, kCacheMountPoint};
+}
// Return true if everything is mounted, but before adb is started. Right
// after 'trigger load_persist_props_action' is done.
@@ -166,26 +194,7 @@
static constexpr unsigned long kSizeThreshold = 8 * 1024 * 1024; // 8MB
return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100)) &&
- (vst.f_bfree * vst.f_bsize) >= kSizeThreshold;
-}
-
-bool fs_mgr_in_recovery() {
- // Check the existence of recovery binary instead of using the compile time
- // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
- // defined, albeit not in recovery. More details: system/core/init/README.md
- return fs_mgr_access("/system/bin/recovery");
-}
-
-bool fs_mgr_is_dsu_running() {
- // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
- // never called in recovery, the return value of android::gsi::IsGsiRunning()
- // is not well-defined. In this case, just return false as being in recovery
- // implies not running a DSU system.
- if (fs_mgr_in_recovery()) return false;
- auto saved_errno = errno;
- auto ret = android::gsi::IsGsiRunning();
- errno = saved_errno;
- return ret;
+ (static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
}
const auto kPhysicalDevice = "/dev/block/by-name/"s;
@@ -300,7 +309,7 @@
std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
if (!fs_mgr_is_dir(mount_point)) return "";
const auto base = android::base::Basename(mount_point) + "/";
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
auto upper = dir + kUpperName;
if (!fs_mgr_is_dir(upper)) continue;
@@ -1344,7 +1353,7 @@
if (candidates.empty()) return ret;
std::string dir;
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
if (backing && backing[0] && (overlay_mount_point != backing)) continue;
if (overlay_mount_point == kScratchMountPoint) {
if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
@@ -1465,7 +1474,7 @@
}
}
bool should_destroy_scratch = false;
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
ret &= fs_mgr_overlayfs_teardown_one(
overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change,
overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
@@ -1569,7 +1578,7 @@
constexpr bool* ignore_change = nullptr;
// Teardown legacy overlay mount points that's not backed by a scratch device.
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
if (overlay_mount_point == kScratchMountPoint) {
continue;
}
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h
index 417fb38..6a38401 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -22,11 +22,16 @@
#include <utility>
#include <vector>
-std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline);
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline);
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& key,
std::string* out_val);
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val);
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig(
+ const std::string& bootconfig);
+bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const std::string& key,
+ std::string* out_val);
+bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val);
#endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 745dab2..e685070 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -411,19 +411,26 @@
auto blk_device = entry.blk_device;
auto mount_point = entry.mount_point;
+ auto found = false;
for (auto it = mounts.rbegin(); it != mounts.rend(); ++it) {
auto& rentry = *it;
if (mount_point == rentry.mount_point) {
blk_device = rentry.blk_device;
+ found = true;
break;
}
// Find overlayfs mount point?
if ((mount_point == "/") && (rentry.mount_point == "/system")) {
blk_device = rentry.blk_device;
mount_point = "/system";
+ found = true;
break;
}
}
+ if (!found) {
+ PLOG(INFO) << "skip unmounted partition dev:" << blk_device << " mnt:" << mount_point;
+ continue;
+ }
if (blk_device == "/dev/root") {
auto from_fstab = GetEntryForMountPoint(&fstab, mount_point);
if (from_fstab) blk_device = from_fstab->blk_device;
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index 0efe384..428a7f4 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libdm",
defaults: ["fs_mgr_defaults"],
diff --git a/fs_mgr/libfiemap/Android.bp b/fs_mgr/libfiemap/Android.bp
index a622110..1c5872e 100644
--- a/fs_mgr/libfiemap/Android.bp
+++ b/fs_mgr/libfiemap/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libfiemap_headers",
recovery_available: true,
diff --git a/fs_mgr/libfiemap/fiemap_writer.cpp b/fs_mgr/libfiemap/fiemap_writer.cpp
index 621031a..8acb885 100644
--- a/fs_mgr/libfiemap/fiemap_writer.cpp
+++ b/fs_mgr/libfiemap/fiemap_writer.cpp
@@ -52,7 +52,7 @@
static constexpr const uint32_t kUnsupportedExtentFlags =
FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_NOT_ALIGNED | FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_DATA_TAIL |
- FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_SHARED | FIEMAP_EXTENT_MERGED;
+ FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_SHARED;
// Large file support must be enabled.
static_assert(sizeof(off_t) == sizeof(uint64_t));
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index 841f215..44f659b 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -16,6 +16,8 @@
#include <libfiemap/image_manager.h>
+#include <optional>
+
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -574,7 +576,7 @@
return false;
}
auto& dm = DeviceMapper::Instance();
- LoopControl loop;
+ std::optional<LoopControl> loop;
std::string status;
auto status_file = GetStatusFilePath(name);
@@ -598,9 +600,14 @@
return false;
}
} else if (pieces[0] == "loop") {
+ // Lazily connect to loop-control to avoid spurious errors in recovery.
+ if (!loop.has_value()) {
+ loop.emplace();
+ }
+
// Failure to remove a loop device is not fatal, since we can still
// remove the backing file if we want.
- loop.Detach(pieces[1]);
+ loop->Detach(pieces[1]);
} else {
LOG(ERROR) << "Unknown status: " << pieces[0];
}
diff --git a/fs_mgr/libfs_avb/Android.bp b/fs_mgr/libfs_avb/Android.bp
index 45e7a30..c1c181a 100644
--- a/fs_mgr/libfs_avb/Android.bp
+++ b/fs_mgr/libfs_avb/Android.bp
@@ -14,6 +14,16 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_fs_mgr_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["system_core_fs_mgr_license"],
+}
+
cc_library_static {
name: "libfs_avb",
defaults: ["fs_mgr_defaults"],
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index 49333a1..1da7117 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -433,6 +433,16 @@
// Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
+ // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
+ std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
+ if (!avb_verifier || !avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
+ LERROR << "Failed to verify vbmeta digest";
+ if (!allow_verification_error) {
+ LERROR << "vbmeta digest error isn't allowed ";
+ return nullptr;
+ }
+ }
+
// Checks whether FLAGS_VERIFICATION_DISABLED is set:
// - Only the top-level vbmeta struct is read.
// - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
@@ -443,26 +453,16 @@
bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
+ // Checks whether FLAGS_HASHTREE_DISABLED is set.
+ // - vbmeta struct in all partitions are still processed, just disable
+ // dm-verity in the user space.
+ bool hashtree_disabled =
+ ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
+
if (verification_disabled) {
avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
- } else {
- // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
- std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
- if (!avb_verifier) {
- LERROR << "Failed to create AvbVerifier";
- return nullptr;
- }
- if (!avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
- LERROR << "VerifyVbmetaImages failed";
- return nullptr;
- }
-
- // Checks whether FLAGS_HASHTREE_DISABLED is set.
- bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
- AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
- if (hashtree_disabled) {
- avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
- }
+ } else if (hashtree_disabled) {
+ avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
}
LINFO << "Returning avb_handle with status: " << avb_handle->status_;
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 9517bd3..7e528b1 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
liblp_lib_deps = [
"libbase",
"liblog",
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index d36a7f0..b808609 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libsnapshot_defaults",
defaults: ["fs_mgr_defaults"],
@@ -549,6 +553,7 @@
],
srcs: [
"cow_snapuserd_test.cpp",
+ "snapuserd.cpp",
],
cflags: [
"-Wall",
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 36e1169..b4e92a2 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -46,7 +46,7 @@
SECOND_PHASE = 2;
}
-// Next: 11
+// Next: 12
message SnapshotStatus {
// Name of the snapshot. This is usually the name of the snapshotted
// logical partition; for example, "system_b".
@@ -102,6 +102,9 @@
// The old partition size (if none existed, this will be zero).
uint64 old_partition_size = 10;
+
+ // Compression algorithm (none, gz, or brotli).
+ string compression_algorithm = 11;
}
// Next: 8
@@ -156,7 +159,7 @@
MergePhase merge_phase = 6;
}
-// Next: 4
+// Next: 5
message SnapshotMergeReport {
// Status of the update after the merge attempts.
UpdateState state = 1;
@@ -167,4 +170,7 @@
// Total size of all the COW images before the update.
uint64 cow_file_size = 3;
+
+ // Whether compression/dm-user was used for any snapshots.
+ bool compression_enabled = 4;
}
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index c15a05b..cf9f6ea 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -181,6 +181,7 @@
ops_buffer->resize(current_op_num);
}
+ LOG(DEBUG) << "COW file read complete. Total ops: " << ops_buffer->size();
// To successfully parse a COW file, we need either:
// (1) a label to read up to, and for that label to be found, or
// (2) a valid footer.
@@ -236,6 +237,7 @@
[](CowOperation& op) { return IsMetadataOp(op); }),
ops_.get()->end());
+ set_total_data_ops(ops_->size());
// We will re-arrange the vector in such a way that
// kernel can batch merge. Ex:
//
@@ -298,10 +300,9 @@
// are contiguous. These are monotonically increasing numbers.
//
// When both (1) and (2) are true, kernel will batch merge the operations.
- // However, we do not want copy operations to be batch merged as
- // a crash or system reboot during an overlapping copy can drive the device
- // to a corrupted state. Hence, merging of copy operations should always be
- // done as a individual 4k block. In the above case, since the
+ // In the above case, we have to ensure that the copy operations
+ // are merged first before replace operations are done. Hence,
+ // we will not change the order of copy operations. Since,
// cow_op->new_block numbers are contiguous, we will ensure that the
// cow block numbers assigned in ReadMetadata() for these respective copy
// operations are not contiguous forcing kernel to issue merge for each
@@ -328,10 +329,8 @@
//
// Merge sequence will look like:
//
- // Merge-1 - Copy-op-1
- // Merge-2 - Copy-op-2
- // Merge-3 - Copy-op-3
- // Merge-4 - Batch-merge {Replace-op-7, Replace-op-6, Zero-op-8,
+ // Merge-1 - Batch-merge { Copy-op-1, Copy-op-2, Copy-op-3 }
+ // Merge-2 - Batch-merge {Replace-op-7, Replace-op-6, Zero-op-8,
// Replace-op-4, Zero-op-9, Replace-op-5 }
//==============================================================
diff --git a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
index 7fa23db..045d9db 100644
--- a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
@@ -36,6 +36,8 @@
#include <libsnapshot/snapuserd_client.h>
#include <storage_literals/storage_literals.h>
+#include "snapuserd.h"
+
namespace android {
namespace snapshot {
@@ -119,7 +121,6 @@
void CreateDmUserDevice();
void StartSnapuserdDaemon();
void CreateSnapshotDevice();
- unique_fd CreateTempFile(const std::string& name, size_t size);
unique_ptr<LoopDevice> base_loop_;
unique_ptr<TempDevice> dmuser_dev_;
@@ -140,7 +141,24 @@
int total_base_size_;
};
-unique_fd CowSnapuserdTest::CreateTempFile(const std::string& name, size_t size) {
+class CowSnapuserdMetadataTest final {
+ public:
+ void Setup();
+ void SetupPartialArea();
+ void ValidateMetadata();
+ void ValidatePartialFilledArea();
+
+ private:
+ void InitMetadata();
+ void CreateCowDevice();
+ void CreateCowPartialFilledArea();
+
+ std::unique_ptr<Snapuserd> snapuserd_;
+ std::unique_ptr<TemporaryFile> cow_system_;
+ size_t size_ = 1_MiB;
+};
+
+static unique_fd CreateTempFile(const std::string& name, size_t size) {
unique_fd fd(syscall(__NR_memfd_create, name.c_str(), MFD_ALLOW_SEALING));
if (fd < 0) {
return {};
@@ -430,25 +448,299 @@
}
void CowSnapuserdTest::MergeInterrupt() {
+ // Interrupt merge at various intervals
StartMerge();
- std::this_thread::sleep_for(4s);
+ std::this_thread::sleep_for(250ms);
SimulateDaemonRestart();
StartMerge();
- std::this_thread::sleep_for(3s);
+ std::this_thread::sleep_for(250ms);
SimulateDaemonRestart();
StartMerge();
- std::this_thread::sleep_for(3s);
+ std::this_thread::sleep_for(150ms);
SimulateDaemonRestart();
StartMerge();
- std::this_thread::sleep_for(1s);
+ std::this_thread::sleep_for(100ms);
+ SimulateDaemonRestart();
+
+ StartMerge();
+ std::this_thread::sleep_for(800ms);
+ SimulateDaemonRestart();
+
+ StartMerge();
+ std::this_thread::sleep_for(600ms);
SimulateDaemonRestart();
ASSERT_TRUE(Merge());
}
+void CowSnapuserdMetadataTest::CreateCowPartialFilledArea() {
+ std::string path = android::base::GetExecutableDirectory();
+ cow_system_ = std::make_unique<TemporaryFile>(path);
+
+ CowOptions options;
+ options.compression = "gz";
+ CowWriter writer(options);
+
+ ASSERT_TRUE(writer.Initialize(cow_system_->fd));
+
+ // Area 0 is completely filled with 256 exceptions
+ for (int i = 0; i < 256; i++) {
+ ASSERT_TRUE(writer.AddCopy(i, 256 + i));
+ }
+
+ // Area 1 is partially filled with 2 copy ops and 10 zero ops
+ ASSERT_TRUE(writer.AddCopy(500, 1000));
+ ASSERT_TRUE(writer.AddCopy(501, 1001));
+
+ ASSERT_TRUE(writer.AddZeroBlocks(300, 10));
+
+ // Flush operations
+ ASSERT_TRUE(writer.Finalize());
+}
+
+void CowSnapuserdMetadataTest::ValidatePartialFilledArea() {
+ int area_sz = snapuserd_->GetMetadataAreaSize();
+
+ ASSERT_EQ(area_sz, 2);
+
+ size_t new_chunk = 263;
+ // Verify the partially filled area
+ void* buffer = snapuserd_->GetExceptionBuffer(1);
+ loff_t offset = 0;
+ struct disk_exception* de;
+ for (int i = 0; i < 12; i++) {
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, i);
+ ASSERT_EQ(de->new_chunk, new_chunk);
+ offset += sizeof(struct disk_exception);
+ new_chunk += 1;
+ }
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 0);
+ ASSERT_EQ(de->new_chunk, 0);
+}
+
+void CowSnapuserdMetadataTest::SetupPartialArea() {
+ CreateCowPartialFilledArea();
+ InitMetadata();
+}
+
+void CowSnapuserdMetadataTest::CreateCowDevice() {
+ unique_fd rnd_fd;
+ loff_t offset = 0;
+
+ std::string path = android::base::GetExecutableDirectory();
+ cow_system_ = std::make_unique<TemporaryFile>(path);
+
+ rnd_fd.reset(open("/dev/random", O_RDONLY));
+ ASSERT_TRUE(rnd_fd > 0);
+
+ std::unique_ptr<uint8_t[]> random_buffer_1_ = std::make_unique<uint8_t[]>(size_);
+
+ // Fill random data
+ for (size_t j = 0; j < (size_ / 1_MiB); j++) {
+ ASSERT_EQ(ReadFullyAtOffset(rnd_fd, (char*)random_buffer_1_.get() + offset, 1_MiB, 0),
+ true);
+
+ offset += 1_MiB;
+ }
+
+ CowOptions options;
+ options.compression = "gz";
+ CowWriter writer(options);
+
+ ASSERT_TRUE(writer.Initialize(cow_system_->fd));
+
+ size_t num_blocks = size_ / options.block_size;
+
+ // Overlapping region. This has to be split
+ // into two batch operations
+ ASSERT_TRUE(writer.AddCopy(23, 20));
+ ASSERT_TRUE(writer.AddCopy(22, 19));
+ ASSERT_TRUE(writer.AddCopy(21, 18));
+ ASSERT_TRUE(writer.AddCopy(20, 17));
+ ASSERT_TRUE(writer.AddCopy(19, 16));
+ ASSERT_TRUE(writer.AddCopy(18, 15));
+
+ // Contiguous region but blocks in ascending order
+ // Daemon has to ensure that these blocks are merged
+ // in a batch
+ ASSERT_TRUE(writer.AddCopy(50, 75));
+ ASSERT_TRUE(writer.AddCopy(51, 76));
+ ASSERT_TRUE(writer.AddCopy(52, 77));
+ ASSERT_TRUE(writer.AddCopy(53, 78));
+
+ // Dis-contiguous region
+ ASSERT_TRUE(writer.AddCopy(110, 130));
+ ASSERT_TRUE(writer.AddCopy(105, 125));
+ ASSERT_TRUE(writer.AddCopy(100, 120));
+
+ // Overlap
+ ASSERT_TRUE(writer.AddCopy(25, 30));
+ ASSERT_TRUE(writer.AddCopy(30, 31));
+
+ size_t source_blk = num_blocks;
+
+ ASSERT_TRUE(writer.AddRawBlocks(source_blk, random_buffer_1_.get(), size_));
+
+ size_t blk_zero_copy_start = source_blk + num_blocks;
+
+ ASSERT_TRUE(writer.AddZeroBlocks(blk_zero_copy_start, num_blocks));
+
+ // Flush operations
+ ASSERT_TRUE(writer.Finalize());
+}
+
+void CowSnapuserdMetadataTest::InitMetadata() {
+ snapuserd_ = std::make_unique<Snapuserd>("", cow_system_->path, "");
+ ASSERT_TRUE(snapuserd_->InitCowDevice());
+}
+
+void CowSnapuserdMetadataTest::Setup() {
+ CreateCowDevice();
+ InitMetadata();
+}
+
+void CowSnapuserdMetadataTest::ValidateMetadata() {
+ int area_sz = snapuserd_->GetMetadataAreaSize();
+ ASSERT_EQ(area_sz, 3);
+
+ size_t old_chunk;
+ size_t new_chunk;
+
+ for (int i = 0; i < area_sz; i++) {
+ void* buffer = snapuserd_->GetExceptionBuffer(i);
+ loff_t offset = 0;
+ if (i == 0) {
+ old_chunk = 256;
+ new_chunk = 2;
+ } else if (i == 1) {
+ old_chunk = 512;
+ new_chunk = 259;
+ }
+ for (int j = 0; j < 256; j++) {
+ struct disk_exception* de =
+ reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+
+ if (i != 2) {
+ ASSERT_EQ(de->old_chunk, old_chunk);
+ ASSERT_EQ(de->new_chunk, new_chunk);
+ old_chunk += 1;
+ new_chunk += 1;
+ } else {
+ break;
+ }
+ offset += sizeof(struct disk_exception);
+ }
+
+ if (i == 2) {
+ // The first 5 copy operation is not batch merged
+ // as the sequence is discontiguous
+ struct disk_exception* de =
+ reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 30);
+ ASSERT_EQ(de->new_chunk, 518);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 25);
+ ASSERT_EQ(de->new_chunk, 520);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 100);
+ ASSERT_EQ(de->new_chunk, 522);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 105);
+ ASSERT_EQ(de->new_chunk, 524);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 110);
+ ASSERT_EQ(de->new_chunk, 526);
+ offset += sizeof(struct disk_exception);
+
+ // The next 4 operations are batch merged as
+ // both old and new chunk are contiguous
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 50);
+ ASSERT_EQ(de->new_chunk, 528);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 51);
+ ASSERT_EQ(de->new_chunk, 529);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 52);
+ ASSERT_EQ(de->new_chunk, 530);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 53);
+ ASSERT_EQ(de->new_chunk, 531);
+ offset += sizeof(struct disk_exception);
+
+ // This is handling overlap operation with
+ // two batch merge operations.
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 18);
+ ASSERT_EQ(de->new_chunk, 533);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 19);
+ ASSERT_EQ(de->new_chunk, 534);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 20);
+ ASSERT_EQ(de->new_chunk, 535);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 21);
+ ASSERT_EQ(de->new_chunk, 537);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 22);
+ ASSERT_EQ(de->new_chunk, 538);
+ offset += sizeof(struct disk_exception);
+
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 23);
+ ASSERT_EQ(de->new_chunk, 539);
+ offset += sizeof(struct disk_exception);
+
+ // End of metadata
+ de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
+ ASSERT_EQ(de->old_chunk, 0);
+ ASSERT_EQ(de->new_chunk, 0);
+ offset += sizeof(struct disk_exception);
+ }
+ }
+}
+
+TEST(Snapuserd_Test, Snapshot_Metadata) {
+ CowSnapuserdMetadataTest harness;
+ harness.Setup();
+ harness.ValidateMetadata();
+}
+
+TEST(Snapuserd_Test, Snapshot_Metadata_Overlap) {
+ CowSnapuserdMetadataTest harness;
+ harness.SetupPartialArea();
+ harness.ValidatePartialFilledArea();
+}
+
TEST(Snapuserd_Test, Snapshot_Merge_Resume) {
CowSnapuserdTest harness;
ASSERT_TRUE(harness.Setup());
@@ -457,7 +749,7 @@
harness.Shutdown();
}
-TEST(Snapuserd_Test, Snapshot) {
+TEST(Snapuserd_Test, Snapshot_IO_TEST) {
CowSnapuserdTest harness;
ASSERT_TRUE(harness.Setup());
harness.ReadSnapshotDeviceAndValidate();
@@ -465,7 +757,6 @@
harness.ValidateMerge();
harness.Shutdown();
}
-
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/cow_writer.cpp b/fs_mgr/libsnapshot/cow_writer.cpp
index c1a5f32..81edc79 100644
--- a/fs_mgr/libsnapshot/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/cow_writer.cpp
@@ -491,7 +491,7 @@
return true;
}
-bool CowWriter::CommitMerge(int merged_ops, bool sync) {
+bool CowWriter::CommitMerge(int merged_ops) {
CHECK(merge_in_progress_);
header_.num_merge_ops += merged_ops;
@@ -506,11 +506,7 @@
return false;
}
- // Sync only for merging of copy operations.
- if (sync) {
- return Sync();
- }
- return true;
+ return Sync();
}
bool CowWriter::Truncate(off_t length) {
diff --git a/fs_mgr/libsnapshot/dm_snapshot_internals.h b/fs_mgr/libsnapshot/dm_snapshot_internals.h
index fef256d..ed77c15 100644
--- a/fs_mgr/libsnapshot/dm_snapshot_internals.h
+++ b/fs_mgr/libsnapshot/dm_snapshot_internals.h
@@ -14,8 +14,10 @@
#pragma once
+#include <android-base/logging.h>
#include <stdint.h>
+#include <optional>
#include <vector>
namespace android {
@@ -26,19 +28,46 @@
DmSnapCowSizeCalculator(unsigned int sector_bytes, unsigned int chunk_sectors)
: sector_bytes_(sector_bytes),
chunk_sectors_(chunk_sectors),
- exceptions_per_chunk(chunk_sectors_ * sector_bytes_ / (64 * 2 / 8)) {}
+ exceptions_per_chunk(chunk_sectors_ * sector_bytes_ / exception_size_bytes) {}
void WriteByte(uint64_t address) { WriteSector(address / sector_bytes_); }
void WriteSector(uint64_t sector) { WriteChunk(sector / chunk_sectors_); }
void WriteChunk(uint64_t chunk_id) {
- if (modified_chunks_.size() <= chunk_id) {
- modified_chunks_.resize(chunk_id + 1, false);
+ if (!valid_) {
+ return;
}
+
+ if (modified_chunks_.size() <= chunk_id) {
+ if (modified_chunks_.max_size() <= chunk_id) {
+ LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
+ valid_ = false;
+ return;
+ }
+ modified_chunks_.resize(chunk_id + 1, false);
+ if (modified_chunks_.size() <= chunk_id) {
+ LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
+ valid_ = false;
+ return;
+ }
+ }
+
modified_chunks_[chunk_id] = true;
}
- uint64_t cow_size_bytes() const { return cow_size_sectors() * sector_bytes_; }
- uint64_t cow_size_sectors() const { return cow_size_chunks() * chunk_sectors_; }
+ std::optional<uint64_t> cow_size_bytes() const {
+ auto sectors = cow_size_sectors();
+ if (!sectors) {
+ return std::nullopt;
+ }
+ return sectors.value() * sector_bytes_;
+ }
+ std::optional<uint64_t> cow_size_sectors() const {
+ auto chunks = cow_size_chunks();
+ if (!chunks) {
+ return std::nullopt;
+ }
+ return chunks.value() * chunk_sectors_;
+ }
/*
* The COW device has a precise internal structure as follows:
@@ -56,7 +85,12 @@
* - chunks addressable by previous map (exceptions_per_chunk)
* - 1 extra chunk
*/
- uint64_t cow_size_chunks() const {
+ std::optional<uint64_t> cow_size_chunks() const {
+ if (!valid_) {
+ LOG(ERROR) << "Invalid COW size.";
+ return std::nullopt;
+ }
+
uint64_t modified_chunks_count = 0;
uint64_t cow_chunks = 0;
@@ -90,19 +124,30 @@
const uint64_t chunk_sectors_;
/*
- * The COW device stores tables to map the modified chunks. Each table
- * has the size of exactly 1 chunk.
- * Each row of the table (also called exception in the kernel) contains two
- * 64 bit indices to identify the corresponding chunk, and this 128 bit row
- * size is a constant.
- * The number of exceptions that each table can contain determines the
- * number of data chunks that separate two consecutive tables. This value
- * is then fundamental to compute the space overhead introduced by the
- * tables in COW devices.
+ * The COW device stores tables to map the modified chunks. Each table has
+ * the size of exactly 1 chunk.
+ * Each entry of the table is called exception and the number of exceptions
+ * that each table can contain determines the number of data chunks that
+ * separate two consecutive tables. This value is then fundamental to
+ * compute the space overhead introduced by the tables in COW devices.
*/
const uint64_t exceptions_per_chunk;
/*
+ * Each row of the table (called exception in the kernel) contains two
+ * 64 bit indices to identify the corresponding chunk, and this 128 bit
+ * pair is constant in size.
+ */
+ static constexpr unsigned int exception_size_bytes = 64 * 2 / 8;
+
+ /*
+ * Validity check for the container.
+ * It may happen that the caller attempts the write of an invalid chunk
+ * identifier, and this misbehavior is accounted and stored in this value.
+ */
+ bool valid_ = true;
+
+ /*
* |modified_chunks_| is a container that keeps trace of the modified
* chunks.
* Multiple options were considered when choosing the most appropriate data
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 62b54f9..1de7473 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -142,6 +142,10 @@
void InitializeMerge();
+ void set_total_data_ops(uint64_t size) { total_data_ops_ = size; }
+
+ uint64_t total_data_ops() { return total_data_ops_; }
+
private:
bool ParseOps(std::optional<uint64_t> label);
@@ -152,6 +156,7 @@
uint64_t fd_size_;
std::optional<uint64_t> last_label_;
std::shared_ptr<std::vector<CowOperation>> ops_;
+ uint64_t total_data_ops_;
};
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
index 22ddfa6..6ffd5d8 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
@@ -101,7 +101,7 @@
bool InitializeAppend(android::base::borrowed_fd fd, uint64_t label);
void InitializeMerge(android::base::borrowed_fd fd, CowHeader* header);
- bool CommitMerge(int merged_ops, bool sync);
+ bool CommitMerge(int merged_ops);
bool Finalize() override;
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
index 92e7910..1e420cb 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
@@ -32,6 +32,7 @@
(const std::function<bool()>& callback, const std::function<bool()>& before_cancel),
(override));
MOCK_METHOD(UpdateState, GetUpdateState, (double* progress), (override));
+ MOCK_METHOD(bool, UpdateUsesCompression, (), (override));
MOCK_METHOD(Return, CreateUpdateSnapshots,
(const chromeos_update_engine::DeltaArchiveManifest& manifest), (override));
MOCK_METHOD(bool, MapUpdateSnapshot,
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index ff7a727..a79a86d 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -170,6 +170,10 @@
// Other: 0
virtual UpdateState GetUpdateState(double* progress = nullptr) = 0;
+ // Returns true if compression is enabled for the current update. This always returns false if
+ // UpdateState is None, or no snapshots have been created.
+ virtual bool UpdateUsesCompression() = 0;
+
// Create necessary COW device / files for OTA clients. New logical partitions will be added to
// group "cow" in target_metadata. Regions of partitions of current_metadata will be
// "write-protected" and snapshotted.
@@ -326,6 +330,7 @@
UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
const std::function<bool()>& before_cancel = {}) override;
UpdateState GetUpdateState(double* progress = nullptr) override;
+ bool UpdateUsesCompression() override;
Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override;
bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
std::string* snapshot_path) override;
@@ -689,8 +694,8 @@
// Call ProcessUpdateState and handle states with special rules before data wipe. Specifically,
// if |allow_forward_merge| and allow-forward-merge indicator exists, initiate merge if
// necessary.
- bool ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
- const std::function<bool()>& callback);
+ UpdateState ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
+ const std::function<bool()>& callback);
// Return device string of a mapped image, or if it is not available, the mapped image path.
bool GetMappedImageDeviceStringOrPath(const std::string& device_name,
@@ -720,6 +725,9 @@
SnapuserdClient* snapuserd_client() const { return snapuserd_client_.get(); }
+ // Helper of UpdateUsesCompression
+ bool UpdateUsesCompression(LockedFile* lock);
+
std::string gsid_dir_;
std::string metadata_dir_;
std::unique_ptr<IDeviceInfo> device_;
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
index d691d4f..96d2deb 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
@@ -28,7 +28,7 @@
virtual ~ISnapshotMergeStats() = default;
// Called when merge starts or resumes.
virtual bool Start() = 0;
- virtual void set_state(android::snapshot::UpdateState state) = 0;
+ virtual void set_state(android::snapshot::UpdateState state, bool using_compression) = 0;
virtual void set_cow_file_size(uint64_t cow_file_size) = 0;
virtual uint64_t cow_file_size() = 0;
@@ -51,7 +51,7 @@
// ISnapshotMergeStats overrides
bool Start() override;
- void set_state(android::snapshot::UpdateState state) override;
+ void set_state(android::snapshot::UpdateState state, bool using_compression) override;
void set_cow_file_size(uint64_t cow_file_size) override;
uint64_t cow_file_size() override;
std::unique_ptr<Result> Finish() override;
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
index cba3560..3365ceb 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
@@ -32,6 +32,7 @@
UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
const std::function<bool()>& before_cancel = {}) override;
UpdateState GetUpdateState(double* progress = nullptr) override;
+ bool UpdateUsesCompression() override;
Return CreateUpdateSnapshots(
const chromeos_update_engine::DeltaArchiveManifest& manifest) override;
bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h
index 7941e68..2b6c8ef 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapuserd_kernel.h
@@ -47,8 +47,8 @@
static constexpr uint32_t CHUNK_SIZE = 8;
static constexpr uint32_t CHUNK_SHIFT = (__builtin_ffs(CHUNK_SIZE) - 1);
-static constexpr uint32_t BLOCK_SIZE = 4096;
-static constexpr uint32_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SIZE) - 1);
+static constexpr uint32_t BLOCK_SZ = 4096;
+static constexpr uint32_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SZ) - 1);
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.cpp b/fs_mgr/libsnapshot/partition_cow_creator.cpp
index da6fc9d..6002043 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.cpp
+++ b/fs_mgr/libsnapshot/partition_cow_creator.cpp
@@ -142,11 +142,11 @@
}
}
-uint64_t PartitionCowCreator::GetCowSize() {
+std::optional<uint64_t> PartitionCowCreator::GetCowSize() {
if (compression_enabled) {
if (update == nullptr || !update->has_estimate_cow_size()) {
LOG(ERROR) << "Update manifest does not include a COW size";
- return 0;
+ return std::nullopt;
}
// Add an extra 2MB of wiggle room for any minor differences in labels/metadata
@@ -239,7 +239,7 @@
}
// Compute the COW partition size.
- uint64_t cow_partition_size = std::min(cow_size, free_region_length);
+ uint64_t cow_partition_size = std::min(cow_size.value(), free_region_length);
// Round it down to the nearest logical block. Logical partitions must be a multiple
// of logical blocks.
cow_partition_size &= ~(logical_block_size - 1);
@@ -247,7 +247,7 @@
// Assign cow_partition_usable_regions to indicate what regions should the COW partition uses.
ret.cow_partition_usable_regions = std::move(free_regions);
- auto cow_file_size = cow_size - cow_partition_size;
+ auto cow_file_size = cow_size.value() - cow_partition_size;
// Round it up to the nearest sector.
cow_file_size += kSectorSize - 1;
cow_file_size &= ~(kSectorSize - 1);
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.h b/fs_mgr/libsnapshot/partition_cow_creator.h
index 64d186b..34b39ca 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.h
+++ b/fs_mgr/libsnapshot/partition_cow_creator.h
@@ -58,6 +58,7 @@
std::vector<ChromeOSExtent> extra_extents = {};
// True if compression is enabled.
bool compression_enabled = false;
+ std::string compression_algorithm;
struct Return {
SnapshotStatus snapshot_status;
@@ -68,7 +69,7 @@
private:
bool HasExtent(Partition* p, Extent* e);
- uint64_t GetCowSize();
+ std::optional<uint64_t> GetCowSize();
};
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/partition_cow_creator_test.cpp b/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
index e4b476f..de35c13 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
+++ b/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
@@ -308,6 +308,10 @@
cc.WriteByte(b);
ASSERT_EQ(cc.cow_size_sectors(), 40);
}
+
+ // Write a byte that would surely overflow the counter
+ cc.WriteChunk(std::numeric_limits<uint64_t>::max());
+ ASSERT_FALSE(cc.cow_size_sectors().has_value());
}
void BlocksToExtents(const std::vector<uint64_t>& blocks,
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 9329725..ca4c265 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -94,7 +94,11 @@
if (!info) {
info = new DeviceInfo();
}
- return std::unique_ptr<SnapshotManager>(new SnapshotManager(info));
+ auto sm = std::unique_ptr<SnapshotManager>(new SnapshotManager(info));
+ if (info->IsRecovery()) {
+ sm->ForceLocalImageManager();
+ }
+ return sm;
}
std::unique_ptr<SnapshotManager> SnapshotManager::NewForFirstStageMount(IDeviceInfo* info) {
@@ -355,6 +359,7 @@
status->set_sectors_allocated(0);
status->set_metadata_sectors(0);
status->set_compression_enabled(cow_creator->compression_enabled);
+ status->set_compression_algorithm(cow_creator->compression_algorithm);
if (!WriteSnapshotStatus(lock, *status)) {
PLOG(ERROR) << "Could not write snapshot status: " << status->name();
@@ -890,6 +895,8 @@
const std::function<bool()>& before_cancel) {
while (true) {
UpdateState state = CheckMergeState(before_cancel);
+ LOG(INFO) << "ProcessUpdateState handling state: " << state;
+
if (state == UpdateState::MergeFailed) {
AcknowledgeMergeFailure();
}
@@ -916,13 +923,15 @@
}
UpdateState state = CheckMergeState(lock.get(), before_cancel);
+ LOG(INFO) << "CheckMergeState for snapshots returned: " << state;
+
if (state == UpdateState::MergeCompleted) {
// Do this inside the same lock. Failures get acknowledged without the
// lock, because flock() might have failed.
AcknowledgeMergeSuccess(lock.get());
} else if (state == UpdateState::Cancelled) {
- if (!RemoveAllUpdateState(lock.get(), before_cancel)) {
- return ReadSnapshotUpdateStatus(lock.get()).state();
+ if (!device_->IsRecovery() && !RemoveAllUpdateState(lock.get(), before_cancel)) {
+ LOG(ERROR) << "Failed to remove all update state after acknowleding cancelled update.";
}
}
return state;
@@ -964,13 +973,23 @@
return UpdateState::MergeFailed;
}
+ auto other_suffix = device_->GetOtherSlotSuffix();
+
bool cancelled = false;
bool failed = false;
bool merging = false;
bool needs_reboot = false;
bool wrong_phase = false;
for (const auto& snapshot : snapshots) {
+ if (android::base::EndsWith(snapshot, other_suffix)) {
+ // This will have triggered an error message in InitiateMerge already.
+ LOG(INFO) << "Skipping merge validation of unexpected snapshot: " << snapshot;
+ continue;
+ }
+
UpdateState snapshot_state = CheckTargetMergeState(lock, snapshot, update_status);
+ LOG(INFO) << "CheckTargetMergeState for " << snapshot << " returned: " << snapshot_state;
+
switch (snapshot_state) {
case UpdateState::MergeFailed:
failed = true;
@@ -1169,7 +1188,7 @@
// indicator that cleanup is needed on reboot. If a factory data reset
// was requested, it doesn't matter, everything will get wiped anyway.
// To make testing easier we consider a /data wipe as cleaned up.
- if (device_->IsRecovery() && !in_factory_data_reset_) {
+ if (device_->IsRecovery()) {
WriteUpdateState(lock, UpdateState::MergeCompleted);
return;
}
@@ -1230,6 +1249,25 @@
return true;
}
+static bool DeleteDmDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
+ auto start = std::chrono::steady_clock::now();
+ auto& dm = DeviceMapper::Instance();
+ while (true) {
+ if (dm.DeleteDeviceIfExists(name)) {
+ break;
+ }
+ auto now = std::chrono::steady_clock::now();
+ auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
+ if (elapsed >= timeout_ms) {
+ LOG(ERROR) << "DeleteDevice timeout: " << name;
+ return false;
+ }
+ std::this_thread::sleep_for(250ms);
+ }
+
+ return true;
+}
+
bool SnapshotManager::CollapseSnapshotDevice(const std::string& name,
const SnapshotStatus& status) {
auto& dm = DeviceMapper::Instance();
@@ -1288,10 +1326,11 @@
if (!dm.DeleteDeviceIfExists(base_name)) {
LOG(ERROR) << "Unable to delete base device for snapshot: " << base_name;
}
- auto source_name = GetSourceDeviceName(name);
- if (!dm.DeleteDeviceIfExists(source_name)) {
- LOG(ERROR) << "Unable to delete source device for snapshot: " << source_name;
+
+ if (!DeleteDmDevice(GetSourceDeviceName(name), 4000ms)) {
+ LOG(ERROR) << "Unable to delete source device for snapshot: " << GetSourceDeviceName(name);
}
+
return true;
}
@@ -1383,9 +1422,6 @@
}
auto misc_name = user_cow_name;
- if (transition == InitTransition::SELINUX_DETACH) {
- misc_name += "-selinux";
- }
DmTable table;
table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
@@ -1418,6 +1454,7 @@
// Wait for ueventd to acknowledge and create the control device node.
std::string control_device = "/dev/dm-user/" + misc_name;
if (!WaitForDevice(control_device, 10s)) {
+ LOG(ERROR) << "dm-user control device no found: " << misc_name;
continue;
}
@@ -1670,6 +1707,7 @@
for (const auto& snapshot : snapshots) {
DmTargetSnapshot::Status current_status;
+ if (!IsSnapshotDevice(snapshot)) continue;
if (!QuerySnapshotStatus(snapshot, nullptr, ¤t_status)) continue;
fake_snapshots_status.sectors_allocated += current_status.sectors_allocated;
@@ -1683,6 +1721,17 @@
return state;
}
+bool SnapshotManager::UpdateUsesCompression() {
+ auto lock = LockShared();
+ if (!lock) return false;
+ return UpdateUsesCompression(lock.get());
+}
+
+bool SnapshotManager::UpdateUsesCompression(LockedFile* lock) {
+ SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock);
+ return update_status.compression_enabled();
+}
+
bool SnapshotManager::ListSnapshots(LockedFile* lock, std::vector<std::string>* snapshots) {
CHECK(lock);
@@ -2107,15 +2156,12 @@
CHECK(lock);
if (!EnsureImageManager()) return false;
- auto& dm = DeviceMapper::Instance();
-
- if (IsCompressionEnabled() && !UnmapDmUserDevice(name)) {
+ if (UpdateUsesCompression(lock) && !UnmapDmUserDevice(name)) {
return false;
}
- auto cow_name = GetCowName(name);
- if (!dm.DeleteDeviceIfExists(cow_name)) {
- LOG(ERROR) << "Cannot unmap " << cow_name;
+ if (!DeleteDmDevice(GetCowName(name), 4000ms)) {
+ LOG(ERROR) << "Cannot unmap: " << GetCowName(name);
return false;
}
@@ -2140,12 +2186,11 @@
return false;
}
- if (!EnsureSnapuserdConnected()) {
- return false;
- }
- if (!snapuserd_client_->WaitForDeviceDelete(dm_user_name)) {
- LOG(ERROR) << "Failed to wait for " << dm_user_name << " control device to delete";
- return false;
+ if (EnsureSnapuserdConnected()) {
+ if (!snapuserd_client_->WaitForDeviceDelete(dm_user_name)) {
+ LOG(ERROR) << "Failed to wait for " << dm_user_name << " control device to delete";
+ return false;
+ }
}
// Ensure the control device is gone so we don't run into ABA problems.
@@ -2616,9 +2661,20 @@
// these devices.
AutoDeviceList created_devices;
- bool use_compression = IsCompressionEnabled() &&
- manifest.dynamic_partition_metadata().vabc_enabled() &&
- !device_->IsRecovery();
+ const auto& dap_metadata = manifest.dynamic_partition_metadata();
+ bool use_compression =
+ IsCompressionEnabled() && dap_metadata.vabc_enabled() && !device_->IsRecovery();
+
+ std::string compression_algorithm;
+ if (use_compression) {
+ compression_algorithm = dap_metadata.vabc_compression_param();
+ if (compression_algorithm.empty()) {
+ // Older OTAs don't set an explicit compression type, so default to gz.
+ compression_algorithm = "gz";
+ }
+ } else {
+ compression_algorithm = "none";
+ }
PartitionCowCreator cow_creator{
.target_metadata = target_metadata.get(),
@@ -2629,6 +2685,7 @@
.update = nullptr,
.extra_extents = {},
.compression_enabled = use_compression,
+ .compression_algorithm = compression_algorithm,
};
auto ret = CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices,
@@ -2873,7 +2930,7 @@
return Return::Error();
}
- CowWriter writer(CowOptions{});
+ CowWriter writer(CowOptions{.compression = it->second.compression_algorithm()});
if (!writer.Initialize(fd) || !writer.Finalize()) {
LOG(ERROR) << "Could not initialize COW device for " << target_partition->name();
return Return::Error();
@@ -2980,7 +3037,7 @@
CHECK(lock);
CowOptions cow_options;
- cow_options.compression = "gz";
+ cow_options.compression = status.compression_algorithm();
cow_options.max_blocks = {status.device_size() / cow_options.block_size};
// Currently we don't support partial snapshots, since partition_cow_creator
@@ -3087,7 +3144,8 @@
std::stringstream ss;
ss << "Update state: " << ReadUpdateState(file.get()) << std::endl;
-
+ ss << "Compression: " << ReadSnapshotUpdateStatus(file.get()).compression_enabled()
+ << std::endl;
ss << "Current slot: " << device_->GetSlotSuffix() << std::endl;
ss << "Boot indicator: booting from " << GetCurrentSlot() << " slot" << std::endl;
ss << "Rollback indicator: "
@@ -3118,6 +3176,7 @@
ss << " cow file size (bytes): " << status.cow_file_size() << std::endl;
ss << " allocated sectors: " << status.sectors_allocated() << std::endl;
ss << " metadata sectors: " << status.metadata_sectors() << std::endl;
+ ss << " compression: " << status.compression_algorithm() << std::endl;
}
os << ss.rdbuf();
return ok;
@@ -3169,7 +3228,7 @@
auto slot_number = SlotNumberForSlotSuffix(device_->GetSlotSuffix());
auto super_path = device_->GetSuperDevice(slot_number);
- if (!CreateLogicalAndSnapshotPartitions(super_path)) {
+ if (!CreateLogicalAndSnapshotPartitions(super_path, 20s)) {
LOG(ERROR) << "Unable to map partitions to complete merge.";
return false;
}
@@ -3182,10 +3241,11 @@
};
in_factory_data_reset_ = true;
- bool ok = ProcessUpdateStateOnDataWipe(true /* allow_forward_merge */, process_callback);
+ UpdateState state =
+ ProcessUpdateStateOnDataWipe(true /* allow_forward_merge */, process_callback);
in_factory_data_reset_ = false;
- if (!ok) {
+ if (state == UpdateState::MergeFailed) {
return false;
}
@@ -3193,6 +3253,16 @@
if (!UnmapAllPartitionsInRecovery()) {
LOG(ERROR) << "Unable to unmap all partitions; fastboot may fail to flash.";
}
+
+ if (state != UpdateState::None) {
+ auto lock = LockExclusive();
+ if (!lock) return false;
+
+ // Zap the update state so the bootloader doesn't think we're still
+ // merging. It's okay if this fails, it's informative only at this
+ // point.
+ WriteUpdateState(lock.get(), UpdateState::None);
+ }
return true;
}
@@ -3209,7 +3279,7 @@
auto slot_number = SlotNumberForSlotSuffix(device_->GetSlotSuffix());
auto super_path = device_->GetSuperDevice(slot_number);
- if (!CreateLogicalAndSnapshotPartitions(super_path)) {
+ if (!CreateLogicalAndSnapshotPartitions(super_path, 20s)) {
LOG(ERROR) << "Unable to map partitions to complete merge.";
return false;
}
@@ -3227,15 +3297,15 @@
return true;
}
-bool SnapshotManager::ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
- const std::function<bool()>& callback) {
+UpdateState SnapshotManager::ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
+ const std::function<bool()>& callback) {
auto slot_number = SlotNumberForSlotSuffix(device_->GetSlotSuffix());
UpdateState state = ProcessUpdateState(callback);
LOG(INFO) << "Update state in recovery: " << state;
switch (state) {
case UpdateState::MergeFailed:
LOG(ERROR) << "Unrecoverable merge failure detected.";
- return false;
+ return state;
case UpdateState::Unverified: {
// If an OTA was just applied but has not yet started merging:
//
@@ -3255,8 +3325,12 @@
if (allow_forward_merge &&
access(GetForwardMergeIndicatorPath().c_str(), F_OK) == 0) {
LOG(INFO) << "Forward merge allowed, initiating merge now.";
- return InitiateMerge() &&
- ProcessUpdateStateOnDataWipe(false /* allow_forward_merge */, callback);
+
+ if (!InitiateMerge()) {
+ LOG(ERROR) << "Failed to initiate merge on data wipe.";
+ return UpdateState::MergeFailed;
+ }
+ return ProcessUpdateStateOnDataWipe(false /* allow_forward_merge */, callback);
}
LOG(ERROR) << "Reverting to old slot since update will be deleted.";
@@ -3274,7 +3348,7 @@
default:
break;
}
- return true;
+ return state;
}
bool SnapshotManager::EnsureNoOverflowSnapshot(LockedFile* lock) {
@@ -3355,7 +3429,7 @@
auto slot_suffix = device_->GetOtherSlotSuffix();
auto slot_number = SlotNumberForSlotSuffix(slot_suffix);
auto super_path = device_->GetSuperDevice(slot_number);
- if (!CreateLogicalAndSnapshotPartitions(super_path)) {
+ if (!CreateLogicalAndSnapshotPartitions(super_path, 20s)) {
LOG(ERROR) << "Unable to map partitions.";
return CreateResult::ERROR;
}
diff --git a/fs_mgr/libsnapshot/snapshot_stats.cpp b/fs_mgr/libsnapshot/snapshot_stats.cpp
index 3723730..513700d 100644
--- a/fs_mgr/libsnapshot/snapshot_stats.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stats.cpp
@@ -84,8 +84,9 @@
return WriteState();
}
-void SnapshotMergeStats::set_state(android::snapshot::UpdateState state) {
+void SnapshotMergeStats::set_state(android::snapshot::UpdateState state, bool using_compression) {
report_.set_state(state);
+ report_.set_compression_enabled(using_compression);
}
void SnapshotMergeStats::set_cow_file_size(uint64_t cow_file_size) {
diff --git a/fs_mgr/libsnapshot/snapshot_stub.cpp b/fs_mgr/libsnapshot/snapshot_stub.cpp
index 26b9129..8a254c9 100644
--- a/fs_mgr/libsnapshot/snapshot_stub.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stub.cpp
@@ -116,9 +116,14 @@
return nullptr;
}
+bool SnapshotManagerStub::UpdateUsesCompression() {
+ LOG(ERROR) << __FUNCTION__ << " should never be called.";
+ return false;
+}
+
class SnapshotMergeStatsStub : public ISnapshotMergeStats {
bool Start() override { return false; }
- void set_state(android::snapshot::UpdateState) override {}
+ void set_state(android::snapshot::UpdateState, bool) override {}
void set_cow_file_size(uint64_t) override {}
uint64_t cow_file_size() override { return 0; }
std::unique_ptr<Result> Finish() override { return nullptr; }
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 95e7d89..25500b5 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -423,6 +423,11 @@
PartitionCowCreator cow_creator;
cow_creator.compression_enabled = IsCompressionEnabled();
+ if (cow_creator.compression_enabled) {
+ cow_creator.compression_algorithm = "gz";
+ } else {
+ cow_creator.compression_algorithm = "none";
+ }
static const uint64_t kDeviceSize = 1024 * 1024;
SnapshotStatus status;
@@ -446,6 +451,7 @@
ASSERT_EQ(status.device_size(), kDeviceSize);
ASSERT_EQ(status.snapshot_size(), kDeviceSize);
ASSERT_EQ(status.compression_enabled(), cow_creator.compression_enabled);
+ ASSERT_EQ(status.compression_algorithm(), cow_creator.compression_algorithm);
}
ASSERT_TRUE(sm->UnmapSnapshot(lock_.get(), "test-snapshot"));
@@ -576,6 +582,11 @@
SnapshotStatus status;
ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
ASSERT_EQ(status.state(), SnapshotState::CREATED);
+ if (IsCompressionEnabled()) {
+ ASSERT_EQ(status.compression_algorithm(), "gz");
+ } else {
+ ASSERT_EQ(status.compression_algorithm(), "none");
+ }
DeviceMapper::TargetInfo target;
ASSERT_TRUE(init->IsSnapshotDevice("test_partition_b", &target));
@@ -636,8 +647,8 @@
// Because the status is Merging, we must call ProcessUpdateState, which should
// detect a cancelled update.
- ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::Cancelled);
- ASSERT_EQ(sm->GetUpdateState(), UpdateState::None);
+ ASSERT_EQ(init->ProcessUpdateState(), UpdateState::Cancelled);
+ ASSERT_EQ(init->GetUpdateState(), UpdateState::None);
}
TEST_F(SnapshotTest, UpdateBootControlHal) {
@@ -1160,6 +1171,11 @@
// Test that shrinking and growing partitions at the same time is handled
// correctly in VABC.
TEST_F(SnapshotUpdateTest, SpaceSwapUpdate) {
+ if (!IsCompressionEnabled()) {
+ // b/179111359
+ GTEST_SKIP() << "Skipping Virtual A/B Compression test";
+ }
+
// OTA client blindly unmaps all partitions that are possibly mapped.
for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
@@ -1762,7 +1778,7 @@
ASSERT_TRUE(new_sm->HandleImminentDataWipe());
// Manually mount metadata so that we can call GetUpdateState() below.
MountMetadata();
- EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::Unverified);
+ EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
EXPECT_TRUE(test_device->IsSlotUnbootable(1));
EXPECT_FALSE(test_device->IsSlotUnbootable(0));
}
@@ -2100,8 +2116,12 @@
// There should be no snapshot to merge.
auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, flashed_slot_suffix));
- // update_enigne calls ProcessUpdateState first -- should see Cancelled.
- ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
+ if (flashed_slot == 0 && after_merge) {
+ ASSERT_EQ(UpdateState::MergeCompleted, new_sm->ProcessUpdateState());
+ } else {
+ // update_engine calls ProcessUpdateState first -- should see Cancelled.
+ ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
+ }
// Next OTA calls CancelUpdate no matter what.
ASSERT_TRUE(new_sm->CancelUpdate());
diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index 82db0d3..4c4a342 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -17,6 +17,8 @@
#include "snapuserd.h"
#include <csignal>
+#include <optional>
+#include <set>
#include <libsnapshot/snapuserd_client.h>
@@ -32,7 +34,7 @@
static constexpr size_t PAYLOAD_SIZE = (1UL << 20);
-static_assert(PAYLOAD_SIZE >= BLOCK_SIZE);
+static_assert(PAYLOAD_SIZE >= BLOCK_SZ);
void BufferSink::Initialize(size_t size) {
buffer_size_ = size;
@@ -78,10 +80,10 @@
// request will always be 4k. After constructing
// the header, zero out the remaining block.
void Snapuserd::ConstructKernelCowHeader() {
- void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SIZE);
+ void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SZ);
CHECK(buffer != nullptr);
- memset(buffer, 0, BLOCK_SIZE);
+ memset(buffer, 0, BLOCK_SZ);
struct disk_header* dh = reinterpret_cast<struct disk_header*>(buffer);
@@ -106,13 +108,13 @@
// Start the copy operation. This will read the backing
// block device which is represented by cow_op->source.
bool Snapuserd::ProcessCopyOp(const CowOperation* cow_op) {
- void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SIZE);
+ void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SZ);
CHECK(buffer != nullptr);
// Issue a single 4K IO. However, this can be optimized
// if the successive blocks are contiguous.
- if (!android::base::ReadFullyAtOffset(backing_store_fd_, buffer, BLOCK_SIZE,
- cow_op->source * BLOCK_SIZE)) {
+ if (!android::base::ReadFullyAtOffset(backing_store_fd_, buffer, BLOCK_SZ,
+ cow_op->source * BLOCK_SZ)) {
SNAP_PLOG(ERROR) << "Copy-op failed. Read from backing store: " << backing_store_device_
<< "at block :" << cow_op->source;
return false;
@@ -123,10 +125,10 @@
bool Snapuserd::ProcessZeroOp() {
// Zero out the entire block
- void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SIZE);
+ void* buffer = bufsink_.GetPayloadBuffer(BLOCK_SZ);
CHECK(buffer != nullptr);
- memset(buffer, 0, BLOCK_SIZE);
+ memset(buffer, 0, BLOCK_SZ);
return true;
}
@@ -173,11 +175,11 @@
struct dm_user_message* msg = (struct dm_user_message*)(&(buffer[0]));
memmove(msg->payload.buf, (char*)msg->payload.buf + skip_sector_size,
- (BLOCK_SIZE - skip_sector_size));
+ (BLOCK_SZ - skip_sector_size));
}
bufsink_.ResetBufferOffset();
- return std::min(size, (BLOCK_SIZE - skip_sector_size));
+ return std::min(size, (BLOCK_SZ - skip_sector_size));
}
/*
@@ -234,7 +236,7 @@
return ReadUnalignedSector(sector, size, it);
}
- int num_ops = DIV_ROUND_UP(size, BLOCK_SIZE);
+ int num_ops = DIV_ROUND_UP(size, BLOCK_SZ);
while (num_ops) {
if (!ProcessCowOp(it->second)) {
return -1;
@@ -242,7 +244,7 @@
num_ops -= 1;
it++;
// Update the buffer offset
- bufsink_.UpdateBufferOffset(BLOCK_SIZE);
+ bufsink_.UpdateBufferOffset(BLOCK_SZ);
SNAP_LOG(DEBUG) << "ReadData at sector: " << sector << " size: " << size;
}
@@ -344,7 +346,7 @@
}
int Snapuserd::GetNumberOfMergedOps(void* merged_buffer, void* unmerged_buffer, loff_t offset,
- int unmerged_exceptions, bool* copy_op) {
+ int unmerged_exceptions) {
int merged_ops_cur_iter = 0;
// Find the operations which are merged in this cycle.
@@ -362,10 +364,8 @@
offset += sizeof(struct disk_exception);
const CowOperation* cow_op = chunk_map_[ChunkToSector(cow_de->new_chunk)];
CHECK(cow_op != nullptr);
+
CHECK(cow_op->new_block == cow_de->old_chunk);
- if (cow_op->type == kCowCopyOp) {
- *copy_op = true;
- }
// zero out to indicate that operation is merged.
cow_de->old_chunk = 0;
cow_de->new_chunk = 0;
@@ -389,10 +389,6 @@
return -1;
}
}
-
- if (*copy_op) {
- CHECK(merged_ops_cur_iter == 1);
- }
return merged_ops_cur_iter;
}
@@ -414,47 +410,21 @@
int unmerged_exceptions = 0;
loff_t offset = GetMergeStartOffset(buffer, vec_[divresult.quot].get(), &unmerged_exceptions);
- bool copy_op = false;
- // Check if the merged operation is a copy operation. If so, then we need
- // to explicitly sync the metadata before initiating the next merge.
- // For ex: Consider a following sequence of copy operations in the COW file:
- //
- // Op-1: Copy 2 -> 3
- // Op-2: Copy 1 -> 2
- // Op-3: Copy 5 -> 10
- //
- // Op-1 and Op-2 are overlapping copy operations. The merge sequence will
- // look like:
- //
- // Merge op-1: Copy 2 -> 3
- // Merge op-2: Copy 1 -> 2
- // Merge op-3: Copy 5 -> 10
- //
- // Now, let's say we have a crash _after_ Merge op-2; Block 2 contents would
- // have been over-written by Block-1 after merge op-2. During next reboot,
- // kernel will request the metadata for all the un-merged blocks. If we had
- // not sync the metadata after Merge-op 1 and Merge op-2, snapuser daemon
- // will think that these merge operations are still pending and hence will
- // inform the kernel that Op-1 and Op-2 are un-merged blocks. When kernel
- // resumes back the merging process, it will attempt to redo the Merge op-1
- // once again. However, block 2 contents are wrong as it has the contents
- // of block 1 from previous merge cycle. Although, merge will silently succeed,
- // this will lead to silent data corruption.
- //
- int merged_ops_cur_iter = GetNumberOfMergedOps(buffer, vec_[divresult.quot].get(), offset,
- unmerged_exceptions, ©_op);
+ int merged_ops_cur_iter =
+ GetNumberOfMergedOps(buffer, vec_[divresult.quot].get(), offset, unmerged_exceptions);
// There should be at least one operation merged in this cycle
CHECK(merged_ops_cur_iter > 0);
header.num_merge_ops += merged_ops_cur_iter;
reader_->UpdateMergeProgress(merged_ops_cur_iter);
- if (!writer_->CommitMerge(merged_ops_cur_iter, copy_op)) {
+ if (!writer_->CommitMerge(merged_ops_cur_iter)) {
SNAP_LOG(ERROR) << "CommitMerge failed... merged_ops_cur_iter: " << merged_ops_cur_iter;
return false;
}
SNAP_LOG(DEBUG) << "Merge success: " << merged_ops_cur_iter << "chunk: " << chunk;
+ merge_initiated_ = true;
return true;
}
@@ -476,6 +446,18 @@
return next_chunk;
}
+void Snapuserd::CheckMergeCompletionStatus() {
+ if (!merge_initiated_) {
+ SNAP_LOG(INFO) << "Merge was not initiated. Total-data-ops: " << reader_->total_data_ops();
+ return;
+ }
+
+ CowHeader header;
+ reader_->GetHeader(&header);
+ SNAP_LOG(INFO) << "Merge-status: Total-Merged-ops: " << header.num_merge_ops
+ << " Total-data-ops: " << reader_->total_data_ops();
+}
+
/*
* Read the metadata from COW device and
* construct the metadata as required by the kernel.
@@ -506,12 +488,13 @@
* during merge; specifically when the merge operation has dependency.
* These dependencies can only happen during copy operations.
*
- * To avoid this problem, we make sure that no two copy-operations
- * do not have contiguous chunk IDs. Additionally, we make sure
- * that each copy operation is merged individually.
+ * To avoid this problem, we make sure overlap copy operations
+ * are not batch merged.
* 6: Use a monotonically increasing chunk number to assign the
* new_chunk
- * 7: Each chunk-id represents either a: Metadata page or b: Data page
+ * 7: Each chunk-id represents either
+ * a: Metadata page or
+ * b: Data page
* 8: Chunk-id representing a data page is stored in a map.
* 9: Chunk-id representing a metadata page is converted into a vector
* index. We store this in vector as kernel requests metadata during
@@ -531,10 +514,10 @@
reader_ = std::make_unique<CowReader>();
CowHeader header;
CowOptions options;
- bool prev_copy_op = false;
bool metadata_found = false;
+ int replace_ops = 0, zero_ops = 0, copy_ops = 0;
- SNAP_LOG(DEBUG) << "ReadMetadata Start...";
+ SNAP_LOG(DEBUG) << "ReadMetadata: Parsing cow file";
if (!reader_->Parse(cow_fd_)) {
SNAP_LOG(ERROR) << "Failed to parse";
@@ -546,10 +529,10 @@
return false;
}
- CHECK(header.block_size == BLOCK_SIZE);
+ CHECK(header.block_size == BLOCK_SZ);
- SNAP_LOG(DEBUG) << "Merge-ops: " << header.num_merge_ops;
reader_->InitializeMerge();
+ SNAP_LOG(DEBUG) << "Merge-ops: " << header.num_merge_ops;
writer_ = std::make_unique<CowWriter>(options);
writer_->InitializeMerge(cow_fd_.get(), &header);
@@ -584,17 +567,26 @@
}
metadata_found = true;
- if ((cow_op->type == kCowCopyOp || prev_copy_op)) {
+ // This loop will handle all the replace and zero ops.
+ // We will handle the copy ops later as it requires special
+ // handling of assigning chunk-id's. Furthermore, we make
+ // sure that replace/zero and copy ops are not batch merged; hence,
+ // the bump in the chunk_id before break of this loop
+ if (cow_op->type == kCowCopyOp) {
data_chunk_id = GetNextAllocatableChunkId(data_chunk_id);
+ break;
}
- prev_copy_op = (cow_op->type == kCowCopyOp);
+ if (cow_op->type == kCowReplaceOp) {
+ replace_ops++;
+ } else if (cow_op->type == kCowZeroOp) {
+ zero_ops++;
+ }
// Construct the disk-exception
de->old_chunk = cow_op->new_block;
de->new_chunk = data_chunk_id;
- SNAP_LOG(DEBUG) << "Old-chunk: " << de->old_chunk << "New-chunk: " << de->new_chunk;
// Store operation pointer.
chunk_map_[ChunkToSector(data_chunk_id)] = cow_op;
@@ -602,6 +594,9 @@
offset += sizeof(struct disk_exception);
cowop_riter_->Next();
+ SNAP_LOG(DEBUG) << num_ops << ":"
+ << " Old-chunk: " << de->old_chunk << " New-chunk: " << de->new_chunk;
+
if (num_ops == exceptions_per_area_) {
// Store it in vector at the right index. This maps the chunk-id to
// vector index.
@@ -616,13 +611,213 @@
if (cowop_riter_->Done()) {
vec_.push_back(std::move(de_ptr));
- SNAP_LOG(DEBUG) << "ReadMetadata() completed; Number of Areas: " << vec_.size();
}
}
data_chunk_id = GetNextAllocatableChunkId(data_chunk_id);
}
+ std::optional<chunk_t> prev_id = {};
+ std::map<uint64_t, const CowOperation*> map;
+ std::set<uint64_t> dest_blocks;
+ size_t pending_copy_ops = exceptions_per_area_ - num_ops;
+ SNAP_LOG(INFO) << " Processing copy-ops at Area: " << vec_.size()
+ << " Number of replace/zero ops completed in this area: " << num_ops
+ << " Pending copy ops for this area: " << pending_copy_ops;
+ while (!cowop_riter_->Done()) {
+ do {
+ const CowOperation* cow_op = &cowop_riter_->Get();
+ if (IsMetadataOp(*cow_op)) {
+ cowop_riter_->Next();
+ continue;
+ }
+
+ // We have two cases specific cases:
+ //
+ // =====================================================
+ // Case 1: Overlapping copy regions
+ //
+ // Ex:
+ //
+ // Source -> Destination
+ //
+ // 1: 15 -> 18
+ // 2: 16 -> 19
+ // 3: 17 -> 20
+ // 4: 18 -> 21
+ // 5: 19 -> 22
+ // 6: 20 -> 23
+ //
+ // We have 6 copy operations to be executed in OTA and there is a overlap. Update-engine
+ // will write to COW file as follows:
+ //
+ // Op-1: 20 -> 23
+ // Op-2: 19 -> 22
+ // Op-3: 18 -> 21
+ // Op-4: 17 -> 20
+ // Op-5: 16 -> 19
+ // Op-6: 15 -> 18
+ //
+ // Note that the blocks numbers are contiguous. Hence, all 6 copy
+ // operations can potentially be batch merged. However, that will be
+ // problematic if we have a crash as block 20, 19, 18 would have
+ // been overwritten and hence subsequent recovery may end up with
+ // a silent data corruption when op-1, op-2 and op-3 are
+ // re-executed.
+ //
+ // We will split these 6 operations into two batches viz:
+ //
+ // Batch-1:
+ // ===================
+ // Op-1: 20 -> 23
+ // Op-2: 19 -> 22
+ // Op-3: 18 -> 21
+ // ===================
+ //
+ // Batch-2:
+ // ==================
+ // Op-4: 17 -> 20
+ // Op-5: 16 -> 19
+ // Op-6: 15 -> 18
+ // ==================
+ //
+ // Now, merge sequence will look like:
+ //
+ // 1: Merge Batch-1 { op-1, op-2, op-3 }
+ // 2: Update Metadata in COW File that op-1, op-2, op-3 merge is
+ // done.
+ // 3: Merge Batch-2
+ // 4: Update Metadata in COW File that op-4, op-5, op-6 merge is
+ // done.
+ //
+ // Note, that the order of block operations are still the same.
+ // However, we have two batch merge operations. Any crash between
+ // either of this sequence should be safe as each of these
+ // batches are self-contained.
+ //
+ //===========================================================
+ //
+ // Case 2:
+ //
+ // Let's say we have three copy operations written to COW file
+ // in the following order:
+ //
+ // op-1: 15 -> 18
+ // op-2: 16 -> 19
+ // op-3: 17 -> 20
+ //
+ // As aforementioned, kernel will initiate merge in reverse order.
+ // Hence, we will read these ops in reverse order so that all these
+ // ops are exectued in the same order as requested. Thus, we will
+ // read the metadata in reverse order and for the kernel it will
+ // look like:
+ //
+ // op-3: 17 -> 20
+ // op-2: 16 -> 19
+ // op-1: 15 -> 18 <-- Merge starts here in the kernel
+ //
+ // Now, this is problematic as kernel cannot batch merge them.
+ //
+ // Merge sequence will look like:
+ //
+ // Merge-1: op-1: 15 -> 18
+ // Merge-2: op-2: 16 -> 19
+ // Merge-3: op-3: 17 -> 20
+ //
+ // We have three merge operations.
+ //
+ // Even though the blocks are contiguous, kernel can batch merge
+ // them if the blocks are in descending order. Update engine
+ // addresses this issue partially for overlapping operations as
+ // we see that op-1 to op-3 and op-4 to op-6 operatiosn are in
+ // descending order. However, if the copy operations are not
+ // overlapping, update engine cannot write these blocks
+ // in descending order. Hence, we will try to address it.
+ // Thus, we will send these blocks to the kernel and it will
+ // look like:
+ //
+ // op-3: 15 -> 18
+ // op-2: 16 -> 19
+ // op-1: 17 -> 20 <-- Merge starts here in the kernel
+ //
+ // Now with this change, we can batch merge all these three
+ // operations. Merge sequence will look like:
+ //
+ // Merge-1: {op-1: 17 -> 20, op-2: 16 -> 19, op-3: 15 -> 18}
+ //
+ // Note that we have changed the ordering of merge; However, this
+ // is ok as each of these copy operations are independent and there
+ // is no overlap.
+ //
+ //===================================================================
+ if (prev_id.has_value()) {
+ chunk_t diff = (cow_op->new_block > prev_id.value())
+ ? (cow_op->new_block - prev_id.value())
+ : (prev_id.value() - cow_op->new_block);
+ if (diff != 1) {
+ break;
+ }
+ if (dest_blocks.count(cow_op->new_block) || map.count(cow_op->source) > 0) {
+ break;
+ }
+ }
+ metadata_found = true;
+ pending_copy_ops -= 1;
+ map[cow_op->new_block] = cow_op;
+ dest_blocks.insert(cow_op->source);
+ prev_id = cow_op->new_block;
+ cowop_riter_->Next();
+ } while (!cowop_riter_->Done() && pending_copy_ops);
+
+ data_chunk_id = GetNextAllocatableChunkId(data_chunk_id);
+ SNAP_LOG(DEBUG) << "Batch Merge copy-ops of size: " << map.size()
+ << " Area: " << vec_.size() << " Area offset: " << offset
+ << " Pending-copy-ops in this area: " << pending_copy_ops;
+
+ for (auto it = map.begin(); it != map.end(); it++) {
+ struct disk_exception* de =
+ reinterpret_cast<struct disk_exception*>((char*)de_ptr.get() + offset);
+ de->old_chunk = it->first;
+ de->new_chunk = data_chunk_id;
+
+ // Store operation pointer.
+ chunk_map_[ChunkToSector(data_chunk_id)] = it->second;
+ offset += sizeof(struct disk_exception);
+ num_ops += 1;
+ copy_ops++;
+
+ SNAP_LOG(DEBUG) << num_ops << ":"
+ << " Copy-op: "
+ << " Old-chunk: " << de->old_chunk << " New-chunk: " << de->new_chunk;
+
+ if (num_ops == exceptions_per_area_) {
+ // Store it in vector at the right index. This maps the chunk-id to
+ // vector index.
+ vec_.push_back(std::move(de_ptr));
+ num_ops = 0;
+ offset = 0;
+
+ // Create buffer for next area
+ de_ptr = std::make_unique<uint8_t[]>(exceptions_per_area_ *
+ sizeof(struct disk_exception));
+ memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
+
+ if (cowop_riter_->Done()) {
+ vec_.push_back(std::move(de_ptr));
+ SNAP_LOG(DEBUG) << "ReadMetadata() completed; Number of Areas: " << vec_.size();
+ }
+
+ CHECK(pending_copy_ops == 0);
+ pending_copy_ops = exceptions_per_area_;
+ }
+
+ data_chunk_id = GetNextAllocatableChunkId(data_chunk_id);
+ }
+ map.clear();
+ dest_blocks.clear();
+ prev_id.reset();
+ }
+
// Partially filled area or there is no metadata
// If there is no metadata, fill with zero so that kernel
// is aware that merge is completed.
@@ -632,12 +827,17 @@
<< "Areas : " << vec_.size();
}
- SNAP_LOG(DEBUG) << "ReadMetadata() completed. Final_chunk_id: " << data_chunk_id
- << "Num Sector: " << ChunkToSector(data_chunk_id);
+ SNAP_LOG(INFO) << "ReadMetadata completed. Final-chunk-id: " << data_chunk_id
+ << " Num Sector: " << ChunkToSector(data_chunk_id)
+ << " Replace-ops: " << replace_ops << " Zero-ops: " << zero_ops
+ << " Copy-ops: " << copy_ops << " Areas: " << vec_.size()
+ << " Num-ops-merged: " << header.num_merge_ops
+ << " Total-data-ops: " << reader_->total_data_ops();
// Total number of sectors required for creating dm-user device
num_sectors_ = ChunkToSector(data_chunk_id);
metadata_read_done_ = true;
+ merge_initiated_ = false;
return true;
}
@@ -742,7 +942,7 @@
size_t remaining_size = header->len;
size_t read_size = std::min(PAYLOAD_SIZE, remaining_size);
- CHECK(read_size == BLOCK_SIZE);
+ CHECK(read_size == BLOCK_SZ);
CHECK(header->sector > 0);
chunk_t chunk = SectorToChunk(header->sector);
@@ -793,11 +993,11 @@
// will always be a single 4k.
if (header->sector == 0) {
CHECK(metadata_read_done_ == true);
- CHECK(read_size == BLOCK_SIZE);
+ CHECK(read_size == BLOCK_SZ);
ConstructKernelCowHeader();
SNAP_LOG(DEBUG) << "Kernel header constructed";
} else {
- if (!offset && (read_size == BLOCK_SIZE) &&
+ if (!offset && (read_size == BLOCK_SZ) &&
chunk_map_.find(header->sector) == chunk_map_.end()) {
if (!ReadDiskExceptions(chunk, read_size)) {
SNAP_LOG(ERROR) << "ReadDiskExceptions failed for chunk id: " << chunk
diff --git a/fs_mgr/libsnapshot/snapuserd.h b/fs_mgr/libsnapshot/snapuserd.h
index c01fee3..518d08b 100644
--- a/fs_mgr/libsnapshot/snapuserd.h
+++ b/fs_mgr/libsnapshot/snapuserd.h
@@ -70,6 +70,14 @@
const std::string& GetMiscName() { return misc_name_; }
uint64_t GetNumSectors() { return num_sectors_; }
bool IsAttached() const { return ctrl_fd_ >= 0; }
+ void CheckMergeCompletionStatus();
+ void CloseFds() {
+ ctrl_fd_ = {};
+ cow_fd_ = {};
+ backing_store_fd_ = {};
+ }
+ size_t GetMetadataAreaSize() { return vec_.size(); }
+ void* GetExceptionBuffer(size_t i) { return vec_[i].get(); }
private:
bool DmuserReadRequest();
@@ -96,11 +104,11 @@
loff_t GetMergeStartOffset(void* merged_buffer, void* unmerged_buffer,
int* unmerged_exceptions);
int GetNumberOfMergedOps(void* merged_buffer, void* unmerged_buffer, loff_t offset,
- int unmerged_exceptions, bool* copy_op);
+ int unmerged_exceptions);
bool ProcessMergeComplete(chunk_t chunk, void* buffer);
sector_t ChunkToSector(chunk_t chunk) { return chunk << CHUNK_SHIFT; }
chunk_t SectorToChunk(sector_t sector) { return sector >> CHUNK_SHIFT; }
- bool IsBlockAligned(int read_size) { return ((read_size & (BLOCK_SIZE - 1)) == 0); }
+ bool IsBlockAligned(int read_size) { return ((read_size & (BLOCK_SZ - 1)) == 0); }
std::string cow_device_;
std::string backing_store_device_;
@@ -134,6 +142,7 @@
std::map<sector_t, const CowOperation*> chunk_map_;
bool metadata_read_done_ = false;
+ bool merge_initiated_ = false;
BufferSink bufsink_;
};
diff --git a/fs_mgr/libsnapshot/snapuserd.rc b/fs_mgr/libsnapshot/snapuserd.rc
index f2d21ac..4bf34a2 100644
--- a/fs_mgr/libsnapshot/snapuserd.rc
+++ b/fs_mgr/libsnapshot/snapuserd.rc
@@ -4,3 +4,4 @@
disabled
user root
group root system
+ seclabel u:r:snapuserd:s0
diff --git a/fs_mgr/libsnapshot/snapuserd_server.cpp b/fs_mgr/libsnapshot/snapuserd_server.cpp
index 38abaec..017de3b 100644
--- a/fs_mgr/libsnapshot/snapuserd_server.cpp
+++ b/fs_mgr/libsnapshot/snapuserd_server.cpp
@@ -210,8 +210,11 @@
}
}
+ handler->snapuserd()->CloseFds();
+
auto misc_name = handler->misc_name();
LOG(INFO) << "Handler thread about to exit: " << misc_name;
+ handler->snapuserd()->CheckMergeCompletionStatus();
{
std::lock_guard<std::mutex> lock(lock_);
diff --git a/fs_mgr/libsnapshot/update_engine/update_metadata.proto b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
index 4a97f81..f31ee31 100644
--- a/fs_mgr/libsnapshot/update_engine/update_metadata.proto
+++ b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
@@ -74,6 +74,7 @@
message DynamicPartitionMetadata {
repeated DynamicPartitionGroup groups = 1;
optional bool vabc_enabled = 3;
+ optional string vabc_compression_param = 4;
}
message DeltaArchiveManifest {
diff --git a/fs_mgr/libstorage_literals/Android.bp b/fs_mgr/libstorage_literals/Android.bp
index beb18ef..635ca49 100644
--- a/fs_mgr/libstorage_literals/Android.bp
+++ b/fs_mgr/libstorage_literals/Android.bp
@@ -1,4 +1,8 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libstorage_literals_headers",
host_supported: true,
diff --git a/fs_mgr/libvbmeta/Android.bp b/fs_mgr/libvbmeta/Android.bp
index a299b6e..c197097 100644
--- a/fs_mgr/libvbmeta/Android.bp
+++ b/fs_mgr/libvbmeta/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
libvbmeta_lib_deps = [
"libbase",
"libcrypto",
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index 9ed283a..335da9e 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "CtsFsMgrTestCases",
test_suites: [
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 0df8cf0..242fa93 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -851,6 +851,9 @@
NORMAL=""
fi
+# Set an ERR trap handler to report any unhandled error
+trap 'die "line ${LINENO}: unhandled error"' ERR
+
if ${print_time}; then
echo "${BLUE}[ INFO ]${NORMAL}" start `date` >&2
fi
@@ -878,10 +881,10 @@
[ -z "${D}" -o -n "${ANDROID_SERIAL}" ] || ANDROID_SERIAL=${D}
USB_SERIAL=
if [ -n "${ANDROID_SERIAL}" -a "Darwin" != "${HOSTOS}" ]; then
- USB_SERIAL="`find /sys/devices -name serial | grep usb`"
+ USB_SERIAL="`find /sys/devices -name serial | grep usb || true`"
if [ -n "${USB_SERIAL}" ]; then
USB_SERIAL=`echo "${USB_SERIAL}" |
- xargs grep -l ${ANDROID_SERIAL}`
+ xargs grep -l ${ANDROID_SERIAL} || true`
fi
fi
USB_ADDRESS=
@@ -1178,7 +1181,7 @@
# Feed log with selinux denials as baseline before overlays
adb_unroot
-adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null
+adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
adb_root
D=`adb remount 2>&1`
@@ -1312,7 +1315,7 @@
[ -n "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
echo "${YELLOW}[ WARNING ]${NORMAL} vendor devt ${VENDOR_DEVT} major 0" >&2
-# Download libc.so, append some gargage, push back, and check if the file
+# Download libc.so, append some garbage, push back, and check if the file
# is updated.
tempdir="`mktemp -d`"
cleanup() {
@@ -1320,8 +1323,8 @@
}
adb pull /system/lib/bootstrap/libc.so ${tempdir} >/dev/null ||
die "pull libc.so from device"
-garbage="`hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/random`"
-echo ${garbage} >> ${tempdir}/libc.so
+garbage="D105225BBFCB1EB8AB8EBDB7094646F0"
+echo "${garbage}" >> ${tempdir}/libc.so
adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so >/dev/null ||
die "push libc.so to device"
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
@@ -1365,7 +1368,7 @@
echo "${GREEN}[ OK ]${NORMAL} /vendor content correct MAC after reboot" >&2
# Feed unprivileged log with selinux denials as a result of overlays
wait_for_screen
- adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null
+ adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
fi
# If overlayfs has a nested security problem, this will fail.
B="`adb_ls /system/`" ||
@@ -1392,7 +1395,7 @@
check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" --warning devt for su after reboot
# Feed log with selinux denials as a result of overlays
-adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null
+adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
# Check if the updated libc.so is persistent after reboot.
adb_root &&
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 46f1c59..62a8d3b 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -119,10 +119,73 @@
{"terminator", "truncated"},
};
+const std::string bootconfig =
+ "androidboot.bootdevice = \" \"1d84000.ufshc\"\n"
+ "androidboot.baseband = \"sdy\"\n"
+ "androidboot.keymaster = \"1\"\n"
+ "androidboot.serialno = \"BLAHBLAHBLAH\"\n"
+ "androidboot.slot_suffix = \"_a\"\n"
+ "androidboot.hardware.platform = \"sdw813\"\n"
+ "androidboot.hardware = \"foo\"\n"
+ "androidboot.revision = \"EVT1.0\"\n"
+ "androidboot.bootloader = \"burp-0.1-7521\"\n"
+ "androidboot.hardware.sku = \"mary\"\n"
+ "androidboot.hardware.radio.subtype = \"0\"\n"
+ "androidboot.dtbo_idx = \"2\"\n"
+ "androidboot.mode = \"normal\"\n"
+ "androidboot.hardware.ddr = \"1GB,combuchi,LPDDR4X\"\n"
+ "androidboot.ddr_info = \"combuchiandroidboot.ddr_size=2GB\"\n"
+ "androidboot.hardware.ufs = \"2GB,combushi\"\n"
+ "androidboot.boottime = \"0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123\"\n"
+ "androidboot.ramdump = \"disabled\"\n"
+ "androidboot.vbmeta.device = \"PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb\"\n"
+ "androidboot.vbmeta.avb_version = \"1.1\"\n"
+ "androidboot.vbmeta.device_state = \"unlocked\"\n"
+ "androidboot.vbmeta.hash_alg = \"sha256\"\n"
+ "androidboot.vbmeta.size = \"5248\"\n"
+ "androidboot.vbmeta.digest = \""
+ "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860\"\n"
+ "androidboot.vbmeta.invalidate_on_error = \"yes\"\n"
+ "androidboot.veritymode = \"enforcing\"\n"
+ "androidboot.verifiedbootstate = \"orange\"\n"
+ "androidboot.space = \"sha256 5248 androidboot.nospace = nope\"\n";
+
+const std::vector<std::pair<std::string, std::string>> bootconfig_result_space = {
+ {"androidboot.bootdevice", "1d84000.ufshc"},
+ {"androidboot.baseband", "sdy"},
+ {"androidboot.keymaster", "1"},
+ {"androidboot.serialno", "BLAHBLAHBLAH"},
+ {"androidboot.slot_suffix", "_a"},
+ {"androidboot.hardware.platform", "sdw813"},
+ {"androidboot.hardware", "foo"},
+ {"androidboot.revision", "EVT1.0"},
+ {"androidboot.bootloader", "burp-0.1-7521"},
+ {"androidboot.hardware.sku", "mary"},
+ {"androidboot.hardware.radio.subtype", "0"},
+ {"androidboot.dtbo_idx", "2"},
+ {"androidboot.mode", "normal"},
+ {"androidboot.hardware.ddr", "1GB,combuchi,LPDDR4X"},
+ {"androidboot.ddr_info", "combuchiandroidboot.ddr_size=2GB"},
+ {"androidboot.hardware.ufs", "2GB,combushi"},
+ {"androidboot.boottime", "0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123"},
+ {"androidboot.ramdump", "disabled"},
+ {"androidboot.vbmeta.device", "PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb"},
+ {"androidboot.vbmeta.avb_version", "1.1"},
+ {"androidboot.vbmeta.device_state", "unlocked"},
+ {"androidboot.vbmeta.hash_alg", "sha256"},
+ {"androidboot.vbmeta.size", "5248"},
+ {"androidboot.vbmeta.digest",
+ "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860"},
+ {"androidboot.vbmeta.invalidate_on_error", "yes"},
+ {"androidboot.veritymode", "enforcing"},
+ {"androidboot.verifiedbootstate", "orange"},
+ {"androidboot.space", "sha256 5248 androidboot.nospace = nope"},
+};
+
} // namespace
-TEST(fs_mgr, fs_mgr_parse_boot_config) {
- EXPECT_EQ(result_space, fs_mgr_parse_boot_config(cmdline));
+TEST(fs_mgr, fs_mgr_parse_cmdline) {
+ EXPECT_EQ(result_space, fs_mgr_parse_cmdline(cmdline));
}
TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) {
@@ -140,6 +203,27 @@
EXPECT_TRUE(content.empty()) << content;
}
+TEST(fs_mgr, fs_mgr_parse_bootconfig) {
+ EXPECT_EQ(bootconfig_result_space, fs_mgr_parse_proc_bootconfig(bootconfig));
+}
+
+TEST(fs_mgr, fs_mgr_get_boot_config_from_bootconfig) {
+ std::string content;
+ for (const auto& entry : bootconfig_result_space) {
+ static constexpr char androidboot[] = "androidboot.";
+ if (!android::base::StartsWith(entry.first, androidboot)) continue;
+ auto key = entry.first.substr(strlen(androidboot));
+ EXPECT_TRUE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, &content))
+ << " for " << key;
+ EXPECT_EQ(entry.second, content);
+ }
+
+ EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "vbmeta.avb_versio", &content));
+ EXPECT_TRUE(content.empty()) << content;
+ EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "nospace", &content));
+ EXPECT_TRUE(content.empty()) << content;
+}
+
TEST(fs_mgr, fs_mgr_read_fstab_file_proc_mounts) {
Fstab fstab;
ASSERT_TRUE(ReadFstabFromFile("/proc/mounts", &fstab));
diff --git a/fs_mgr/tools/Android.bp b/fs_mgr/tools/Android.bp
index d6ccc4b..462777d 100644
--- a/fs_mgr/tools/Android.bp
+++ b/fs_mgr/tools/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "dmctl",
srcs: ["dmctl.cpp"],
diff --git a/fs_mgr/tools/dmuserd.cpp b/fs_mgr/tools/dmuserd.cpp
index e50a4a2..6b68b28 100644
--- a/fs_mgr/tools/dmuserd.cpp
+++ b/fs_mgr/tools/dmuserd.cpp
@@ -81,7 +81,7 @@
ssize_t total = 0;
ssize_t once;
- while (total < len) {
+ while (total < static_cast<ssize_t>(len)) {
once = write(fd, buf_c + total, len - total);
if (once < 0) return once;
if (once == 0) {
@@ -99,7 +99,7 @@
ssize_t total = 0;
ssize_t once;
- while (total < len) {
+ while (total < static_cast<ssize_t>(len)) {
once = read(fd, buf_c + total, len - total);
if (once < 0) return once;
if (once == 0) {
diff --git a/gatekeeperd/Android.bp b/gatekeeperd/Android.bp
index d1046df..49e8085 100644
--- a/gatekeeperd/Android.bp
+++ b/gatekeeperd/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "gatekeeperd",
cflags: [
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index 781b4af..f9c0cdd 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -318,6 +318,7 @@
authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
authToken.challenge = hwAuthToken->challenge;
+ authToken.userId = hwAuthToken->user_id;
authToken.authenticatorId = hwAuthToken->authenticator_id;
authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
betoh32(hwAuthToken->authenticator_type));
diff --git a/healthd/Android.bp b/healthd/Android.bp
index 251a45b..ec47f68 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libhealthd_headers",
vendor_available: true,
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index fd810cb..377acb7 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -349,9 +349,14 @@
}
void BatteryMonitor::logValues(void) {
+ logValues(*mHealthInfo, *mHealthdConfig);
+}
+
+void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
+ const struct healthd_config& healthd_config) {
char dmesgline[256];
size_t len;
- const HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
+ const HealthInfo_1_0& props = health_info.legacy.legacy;
if (props.batteryPresent) {
snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "",
@@ -359,17 +364,17 @@
props.batteryHealth, props.batteryStatus);
len = strlen(dmesgline);
- if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
props.batteryCurrent);
}
- if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
+ if (!healthd_config.batteryFullChargePath.isEmpty()) {
len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
props.batteryFullCharge);
}
- if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+ if (!healthd_config.batteryCycleCountPath.isEmpty()) {
len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
props.batteryCycleCount);
}
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index fadb5a5..3cda727 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -66,6 +66,9 @@
void logValues(void);
bool isChargerOnline();
+ static void logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
+ const struct healthd_config& healthd_config);
+
private:
struct healthd_config *mHealthdConfig;
Vector<String8> mChargerNames;
diff --git a/healthd/testdata/Android.bp b/healthd/testdata/Android.bp
index 110c79a..f212538 100644
--- a/healthd/testdata/Android.bp
+++ b/healthd/testdata/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
filegroup {
name: "libhealthd_charger_test_data",
srcs: ["**/*.*"],
diff --git a/init/Android.bp b/init/Android.bp
index 06ecc59..3ff1767 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -14,6 +14,23 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["system_core_init_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_init_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
init_common_sources = [
"action.cpp",
"action_manager.cpp",
@@ -74,7 +91,6 @@
cc_defaults {
name: "init_defaults",
- cpp_std: "experimental",
sanitize: {
misc_undefined: ["signed-integer-overflow"],
},
@@ -236,6 +252,119 @@
visibility: ["//packages/modules/Virtualization/microdroid"],
}
+// This currently is only for the VM usecase.
+// TODO(jiyong): replace init_first_stage in Android.mk with this
+cc_binary {
+ name: "init_first_stage_soong",
+ stem: "init_vendor",
+
+ srcs: [
+ "block_dev_initializer.cpp",
+ "devices.cpp",
+ "first_stage_console.cpp",
+ "first_stage_init.cpp",
+ "first_stage_main.cpp",
+ "first_stage_mount.cpp",
+ "reboot_utils.cpp",
+ "selabel.cpp",
+ "selinux.cpp",
+ "service_utils.cpp",
+ "snapuserd_transition.cpp",
+ "switch_root.cpp",
+ "uevent_listener.cpp",
+ "util.cpp",
+ ],
+
+ static_libs: [
+ "libc++fs",
+ "libfs_avb",
+ "libfs_mgr",
+ "libfec",
+ "libfec_rs",
+ "libsquashfs_utils",
+ "liblogwrap",
+ "libext4_utils",
+ "libcrypto_utils",
+ "libsparse",
+ "libavb",
+ "libkeyutils",
+ "liblp",
+ "libcutils",
+ "libbase",
+ "liblog",
+ "libcrypto_static",
+ "libdl",
+ "libz",
+ "libselinux",
+ "libcap",
+ "libgsi",
+ "libcom.android.sysprop.apex",
+ "liblzma",
+ "libunwindstack_no_dex",
+ "libbacktrace_no_dex",
+ "libmodprobe",
+ "libext2_uuid",
+ "libprotobuf-cpp-lite",
+ "libsnapshot_cow",
+ "libsnapshot_init",
+ "update_metadata-protos",
+ ],
+
+ static_executable: true,
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Werror",
+ "-DALLOW_FIRST_STAGE_CONSOLE=0",
+ "-DALLOW_LOCAL_PROP_OVERRIDE=0",
+ "-DALLOW_PERMISSIVE_SELINUX=0",
+ "-DREBOOT_BOOTLOADER_ON_PANIC=0",
+ "-DWORLD_WRITABLE_KMSG=0",
+ "-DDUMP_ON_UMOUNT_FAILURE=0",
+ "-DSHUTDOWN_ZERO_TIMEOUT=0",
+ "-DLOG_UEVENTS=0",
+ "-DSEPOLICY_VERSION=30", // TODO(jiyong): externalize the version number
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: [
+ "-UALLOW_FIRST_STAGE_CONSOLE",
+ "-DALLOW_FIRST_STAGE_CONSOLE=1",
+
+ "-UALLOW_LOCAL_PROP_OVERRIDE",
+ "-DALLOW_LOCAL_PROP_OVERRIDE=1",
+
+ "-UALLOW_PERMISSIVE_SELINUX",
+ "-DALLOW_PERMISSIVE_SELINUX=1",
+
+ "-UREBOOT_BOOTLOADER_ON_PANIC",
+ "-DREBOOT_BOOTLOADER_ON_PANIC=1",
+
+ "-UWORLD_WRITABLE_KMSG",
+ "-DWORLD_WRITABLE_KMSG=1",
+
+ "-UDUMP_ON_UMOUNT_FAILURE",
+ "-DDUMP_ON_UMOUNT_FAILURE=1",
+ ],
+ },
+
+ eng: {
+ cflags: [
+ "-USHUTDOWN_ZERO_TIMEOUT",
+ "-DSHUTDOWN_ZERO_TIMEOUT=1",
+ ],
+ },
+ },
+
+ sanitize: {
+ misc_undefined: ["signed-integer-overflow"],
+ hwaddress: false,
+ },
+}
+
// Tests
// ------------------------------------------------------------------------------
@@ -336,7 +465,6 @@
cc_binary {
name: "host_init_verifier",
host_supported: true,
- cpp_std: "experimental",
cflags: [
"-Wall",
"-Wextra",
diff --git a/init/Android.mk b/init/Android.mk
index 561d641..65ee385 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -64,6 +64,9 @@
util.cpp \
LOCAL_MODULE := init_first_stage
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
LOCAL_MODULE_STEM := init
LOCAL_FORCE_STATIC_EXECUTABLE := true
@@ -137,6 +140,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init_system
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
LOCAL_REQUIRED_MODULES := \
init_second_stage \
@@ -145,6 +151,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init_vendor
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
LOCAL_REQUIRED_MODULES := \
init_first_stage \
diff --git a/init/README.md b/init/README.md
index 67d55e1..4a262c9 100644
--- a/init/README.md
+++ b/init/README.md
@@ -523,6 +523,11 @@
`interface_start aidl/aidl_lazy_test_1` will start the AIDL service that
provides the `aidl_lazy_test_1` interface.
+`load_exports <path>`
+> Open the file at _path_ and export global environment variables declared
+ there. Each line must be in the format `export <name> <value>`, as described
+ above.
+
`load_system_props`
> (This action is deprecated and no-op.)
@@ -795,6 +800,9 @@
`ro.boottime.init.selinux`
> How long in ns it took to run SELinux stage.
+`ro.boottime.init.modules`
+> How long in ms it took to load kernel modules.
+
`ro.boottime.init.cold_boot_wait`
> How long init waited for ueventd's coldboot phase to end.
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 2a76620..3ffca88 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -151,8 +151,8 @@
For boot time purposes, this is done in parallel across a set of child processes. `ueventd.cpp` in
this directory contains documentation on how the parallelization is done.
-There is an option to parallelize the restorecon function during cold boot as well. This should only
-be done for devices that do not use genfscon, which is the recommended method for labeling sysfs
-nodes. To enable this option, use the below line in a ueventd.rc script:
+There is an option to parallelize the restorecon function during cold boot as well. It is
+recommended that devices use genfscon for labeling sysfs nodes. However, some devices may benefit
+from enabling the parallelization option:
parallel_restorecon enabled
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 6b7d1e9..dcc9582 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -292,6 +292,38 @@
return {};
}
+static Result<void> do_load_exports(const BuiltinArguments& args) {
+ auto file_contents = ReadFile(args[1]);
+ if (!file_contents.ok()) {
+ return Error() << "Could not read input file '" << args[1]
+ << "': " << file_contents.error();
+ }
+
+ auto lines = Split(*file_contents, "\n");
+ for (const auto& line : lines) {
+ if (line.empty()) {
+ continue;
+ }
+
+ auto env = Split(line, " ");
+
+ if (env.size() != 3) {
+ return ErrnoError() << "Expected a line as `export <name> <value>`, found: `" << line
+ << "`";
+ }
+
+ if (env[0] != "export") {
+ return ErrnoError() << "Unknown action: '" << env[0] << "', expected 'export'";
+ }
+
+ if (setenv(env[1].c_str(), env[2].c_str(), 1) == -1) {
+ return ErrnoError() << "Failed to export '" << line << "' from " << args[1];
+ }
+ }
+
+ return {};
+}
+
static Result<void> do_hostname(const BuiltinArguments& args) {
if (auto result = WriteFile("/proc/sys/kernel/hostname", args[1]); !result.ok()) {
return Error() << "Unable to write to /proc/sys/kernel/hostname: " << result.error();
@@ -1404,6 +1436,7 @@
{"interface_restart", {1, 1, {false, do_interface_restart}}},
{"interface_start", {1, 1, {false, do_interface_start}}},
{"interface_stop", {1, 1, {false, do_interface_stop}}},
+ {"load_exports", {1, 1, {false, do_load_exports}}},
{"load_persist_props", {0, 0, {false, do_load_persist_props}}},
{"load_system_props", {0, 0, {false, do_load_system_props}}},
{"loglevel", {1, 1, {false, do_loglevel}}},
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 6954c03..ff75aa3 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -122,7 +122,7 @@
}
#define MODULE_BASE_DIR "/lib/modules"
-bool LoadKernelModules(bool recovery, bool want_console) {
+bool LoadKernelModules(bool recovery, bool want_console, int& modules_loaded) {
struct utsname uts;
if (uname(&uts)) {
LOG(FATAL) << "Failed to get kernel version.";
@@ -164,7 +164,7 @@
dir_path.append(module_dir);
Modprobe m({dir_path}, GetModuleLoadList(recovery, dir_path));
bool retval = m.LoadListedModules(!want_console);
- int modules_loaded = m.GetModuleCount();
+ modules_loaded = m.GetModuleCount();
if (modules_loaded > 0) {
return retval;
}
@@ -172,7 +172,7 @@
Modprobe m({MODULE_BASE_DIR}, GetModuleLoadList(recovery, MODULE_BASE_DIR));
bool retval = m.LoadListedModules(!want_console);
- int modules_loaded = m.GetModuleCount();
+ modules_loaded = m.GetModuleCount();
if (modules_loaded > 0) {
return retval;
}
@@ -209,6 +209,8 @@
CHECKCALL(chmod("/proc/cmdline", 0440));
std::string cmdline;
android::base::ReadFileToString("/proc/cmdline", &cmdline);
+ // Don't expose the raw bootconfig to unprivileged processes.
+ chmod("/proc/bootconfig", 0440);
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
@@ -278,15 +280,33 @@
auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0;
- if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console)) {
+ boot_clock::time_point module_start_time = boot_clock::now();
+ int module_count = 0;
+ if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console,
+ module_count)) {
if (want_console != FirstStageConsoleParam::DISABLED) {
LOG(ERROR) << "Failed to load kernel modules, starting console";
} else {
LOG(FATAL) << "Failed to load kernel modules";
}
}
+ if (module_count > 0) {
+ auto module_elapse_time = std::chrono::duration_cast<std::chrono::milliseconds>(
+ boot_clock::now() - module_start_time);
+ setenv(kEnvInitModuleDurationMs, std::to_string(module_elapse_time.count()).c_str(), 1);
+ LOG(INFO) << "Loaded " << module_count << " kernel modules took "
+ << module_elapse_time.count() << " ms";
+ }
+
+ bool created_devices = false;
if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
+ if (!IsRecoveryMode()) {
+ created_devices = DoCreateDevices();
+ if (!created_devices){
+ LOG(ERROR) << "Failed to create device nodes early";
+ }
+ }
StartConsole(cmdline);
}
@@ -327,7 +347,7 @@
}
}
- if (!DoFirstStageMount()) {
+ if (!DoFirstStageMount(!created_devices)) {
LOG(FATAL) << "Failed to mount required partitions early ...";
}
diff --git a/init/first_stage_init.h b/init/first_stage_init.h
index 7de816f..1211f29 100644
--- a/init/first_stage_init.h
+++ b/init/first_stage_init.h
@@ -22,6 +22,7 @@
int FirstStageMain(int argc, char** argv);
static constexpr char kEnvFirstStageStartedAt[] = "FIRST_STAGE_STARTED_AT";
+static constexpr char kEnvInitModuleDurationMs[] = "INIT_MODULE_DURATION_MS";
} // namespace init
} // namespace android
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 7307237..a11bb28 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -44,6 +44,7 @@
#include "block_dev_initializer.h"
#include "devices.h"
+#include "result.h"
#include "snapuserd_transition.h"
#include "switch_root.h"
#include "uevent.h"
@@ -51,6 +52,7 @@
#include "util.h"
using android::base::ReadFileToString;
+using android::base::Result;
using android::base::Split;
using android::base::StringPrintf;
using android::base::Timer;
@@ -81,7 +83,8 @@
// The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
// based on device tree configurations.
- static std::unique_ptr<FirstStageMount> Create();
+ static Result<std::unique_ptr<FirstStageMount>> Create();
+ bool DoCreateDevices(); // Creates devices and logical partitions from storage devices
bool DoFirstStageMount(); // Mounts fstab entries read from device tree.
bool InitDevices();
@@ -159,7 +162,7 @@
return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
}
-static Fstab ReadFirstStageFstab() {
+static Result<Fstab> ReadFirstStageFstab() {
Fstab fstab;
if (!ReadFstabFromDt(&fstab)) {
if (ReadDefaultFstab(&fstab)) {
@@ -169,7 +172,7 @@
}),
fstab.end());
} else {
- LOG(INFO) << "Failed to fstab for first stage mount";
+ return Error() << "failed to read default fstab for first stage mount";
}
}
return fstab;
@@ -235,22 +238,20 @@
super_partition_name_ = fs_mgr_get_super_partition_name();
}
-std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
+Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
auto fstab = ReadFirstStageFstab();
- if (IsDtVbmetaCompatible(fstab)) {
- return std::make_unique<FirstStageMountVBootV2>(std::move(fstab));
+ if (!fstab.ok()) {
+ return fstab.error();
+ }
+
+ if (IsDtVbmetaCompatible(*fstab)) {
+ return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
} else {
- return std::make_unique<FirstStageMountVBootV1>(std::move(fstab));
+ return std::make_unique<FirstStageMountVBootV1>(std::move(*fstab));
}
}
-bool FirstStageMount::DoFirstStageMount() {
- if (!IsDmLinearEnabled() && fstab_.empty()) {
- // Nothing to mount.
- LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
- return true;
- }
-
+bool FirstStageMount::DoCreateDevices() {
if (!InitDevices()) return false;
// Mount /metadata before creating logical partitions, since we need to
@@ -269,6 +270,16 @@
if (!CreateLogicalPartitions()) return false;
+ return true;
+}
+
+bool FirstStageMount::DoFirstStageMount() {
+ if (!IsDmLinearEnabled() && fstab_.empty()) {
+ // Nothing to mount.
+ LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
+ return true;
+ }
+
if (!MountPartitions()) return false;
return true;
@@ -829,20 +840,35 @@
// Public functions
// ----------------
+// Creates devices and logical partitions from storage devices
+bool DoCreateDevices() {
+ auto fsm = FirstStageMount::Create();
+ if (!fsm.ok()) {
+ LOG(ERROR) << "Failed to create FirstStageMount: " << fsm.error();
+ return false;
+ }
+ return (*fsm)->DoCreateDevices();
+}
+
// Mounts partitions specified by fstab in device tree.
-bool DoFirstStageMount() {
+bool DoFirstStageMount(bool create_devices) {
// Skips first stage mount if we're in recovery mode.
if (IsRecoveryMode()) {
LOG(INFO) << "First stage mount skipped (recovery mode)";
return true;
}
- std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
- if (!handle) {
- LOG(ERROR) << "Failed to create FirstStageMount";
+ auto fsm = FirstStageMount::Create();
+ if (!fsm.ok()) {
+ LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
return false;
}
- return handle->DoFirstStageMount();
+
+ if (create_devices) {
+ if (!(*fsm)->DoCreateDevices()) return false;
+ }
+
+ return (*fsm)->DoFirstStageMount();
}
void SetInitAvbVersionInRecovery() {
@@ -852,8 +878,12 @@
}
auto fstab = ReadFirstStageFstab();
+ if (!fstab.ok()) {
+ LOG(ERROR) << fstab.error();
+ return;
+ }
- if (!IsDtVbmetaCompatible(fstab)) {
+ if (!IsDtVbmetaCompatible(*fstab)) {
LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
return;
}
@@ -863,7 +893,7 @@
// We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
// Open() function returns a valid handle.
// We don't need to mount partitions here in recovery mode.
- FirstStageMountVBootV2 avb_first_mount(std::move(fstab));
+ FirstStageMountVBootV2 avb_first_mount(std::move(*fstab));
if (!avb_first_mount.InitDevices()) {
LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
return;
diff --git a/init/first_stage_mount.h b/init/first_stage_mount.h
index 21d87fd..2f4e663 100644
--- a/init/first_stage_mount.h
+++ b/init/first_stage_mount.h
@@ -19,7 +19,8 @@
namespace android {
namespace init {
-bool DoFirstStageMount();
+bool DoCreateDevices();
+bool DoFirstStageMount(bool create_devices);
void SetInitAvbVersionInRecovery();
} // namespace init
diff --git a/init/init.cpp b/init/init.cpp
index ca2d5da..70d6809 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -713,6 +713,10 @@
SetProperty("ro.boottime.init.selinux",
std::to_string(second_stage_start_time.time_since_epoch().count() -
selinux_start_time_ns));
+ if (auto init_module_time_str = getenv(kEnvInitModuleDurationMs); init_module_time_str) {
+ SetProperty("ro.boottime.init.modules", init_module_time_str);
+ unsetenv(kEnvInitModuleDurationMs);
+ }
}
void SendLoadPersistentPropertiesMessage() {
@@ -723,37 +727,6 @@
}
}
-static Result<void> TransitionSnapuserdAction(const BuiltinArguments&) {
- if (!SnapshotManager::IsSnapshotManagerNeeded() ||
- !android::base::GetBoolProperty(android::snapshot::kVirtualAbCompressionProp, false)) {
- return {};
- }
-
- auto sm = SnapshotManager::New();
- if (!sm) {
- LOG(FATAL) << "Failed to create SnapshotManager, will not transition snapuserd";
- return {};
- }
-
- ServiceList& service_list = ServiceList::GetInstance();
- auto svc = service_list.FindService("snapuserd");
- if (!svc) {
- LOG(FATAL) << "Failed to find snapuserd service, aborting transition";
- return {};
- }
- svc->Start();
- svc->SetShutdownCritical();
-
- if (!sm->PerformSecondStageInitTransition()) {
- LOG(FATAL) << "Failed to transition snapuserd to second-stage";
- }
-
- if (auto pid = GetSnapuserdFirstStagePid()) {
- KillFirstStageSnapuserd(pid.value());
- }
- return {};
-}
-
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
@@ -900,9 +873,7 @@
// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
- am.QueueBuiltinAction(TransitionSnapuserdAction, "TransitionSnapuserd");
// ... so that we can start queuing up actions that require stuff from /dev.
- am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
Keychords keychords;
am.QueueBuiltinAction(
@@ -918,10 +889,6 @@
// Trigger all the boot actions to get us started.
am.QueueEventTrigger("init");
- // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
- // wasn't ready immediately after wait_for_coldboot_done
- am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
-
// Don't mount filesystems or start core system services in charger mode.
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
diff --git a/init/lmkd_service.cpp b/init/lmkd_service.cpp
index dd1ab4d..c982925 100644
--- a/init/lmkd_service.cpp
+++ b/init/lmkd_service.cpp
@@ -79,7 +79,7 @@
}
static void RegisterServices(pid_t exclude_pid) {
- for (const auto& service : ServiceList::GetInstance().services()) {
+ for (const auto& service : ServiceList::GetInstance()) {
auto svc = service.get();
if (svc->oom_score_adjust() != DEFAULT_OOM_SCORE_ADJUST) {
// skip if process is excluded or not yet forked (pid==0)
diff --git a/init/property_service.cpp b/init/property_service.cpp
index ce67386..b722702 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -1180,6 +1180,14 @@
}
}
+static void ProcessBootconfig() {
+ ImportBootconfig([&](const std::string& key, const std::string& value) {
+ if (StartsWith(key, "androidboot.")) {
+ InitPropertySet("ro.boot." + key.substr(12), value);
+ }
+ });
+}
+
void PropertyInit() {
selinux_callback cb;
cb.func_audit = PropertyAuditCallback;
@@ -1198,6 +1206,7 @@
// properties set in DT always have priority over the command-line ones.
ProcessKernelDt();
ProcessKernelCmdline();
+ ProcessBootconfig();
// Propagate the kernel variables to internal variables
// used by init as well as the current required properties.
diff --git a/init/reboot.cpp b/init/reboot.cpp
index e3aaa38..d9acee5 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -85,12 +85,11 @@
static const std::set<std::string> kDebuggingServices{"tombstoned", "logd", "adbd", "console"};
-static std::vector<Service*> GetDebuggingServices(bool only_post_data) {
- std::vector<Service*> ret;
- ret.reserve(kDebuggingServices.size());
+static std::set<std::string> GetPostDataDebuggingServices() {
+ std::set<std::string> ret;
for (const auto& s : ServiceList::GetInstance()) {
- if (kDebuggingServices.count(s->name()) && (!only_post_data || s->is_post_data())) {
- ret.push_back(s.get());
+ if (kDebuggingServices.count(s->name()) && s->is_post_data()) {
+ ret.insert(s->name());
}
}
return ret;
@@ -503,13 +502,18 @@
// Stops given services, waits for them to be stopped for |timeout| ms.
// If terminate is true, then SIGTERM is sent to services, otherwise SIGKILL is sent.
-static void StopServices(const std::vector<Service*>& services, std::chrono::milliseconds timeout,
+// Note that services are stopped in order given by |ServiceList::services_in_shutdown_order|
+// function.
+static void StopServices(const std::set<std::string>& services, std::chrono::milliseconds timeout,
bool terminate) {
LOG(INFO) << "Stopping " << services.size() << " services by sending "
<< (terminate ? "SIGTERM" : "SIGKILL");
std::vector<pid_t> pids;
pids.reserve(services.size());
- for (const auto& s : services) {
+ for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
+ if (services.count(s->name()) == 0) {
+ continue;
+ }
if (s->pid() > 0) {
pids.push_back(s->pid());
}
@@ -529,12 +533,12 @@
// Like StopServices, but also logs all the services that failed to stop after the provided timeout.
// Returns number of violators.
-static int StopServicesAndLogViolations(const std::vector<Service*>& services,
+static int StopServicesAndLogViolations(const std::set<std::string>& services,
std::chrono::milliseconds timeout, bool terminate) {
StopServices(services, timeout, terminate);
int still_running = 0;
- for (const auto& s : services) {
- if (s->IsRunning()) {
+ for (const auto& s : ServiceList::GetInstance()) {
+ if (s->IsRunning() && services.count(s->name())) {
LOG(ERROR) << "[service-misbehaving] : service '" << s->name() << "' is still running "
<< timeout.count() << "ms after receiving "
<< (terminate ? "SIGTERM" : "SIGKILL");
@@ -620,8 +624,7 @@
// watchdogd is a vendor specific component but should be alive to complete shutdown safely.
const std::set<std::string> to_starts{"watchdogd"};
- std::vector<Service*> stop_first;
- stop_first.reserve(ServiceList::GetInstance().services().size());
+ std::set<std::string> stop_first;
for (const auto& s : ServiceList::GetInstance()) {
if (kDebuggingServices.count(s->name())) {
// keep debugging tools until non critical ones are all gone.
@@ -639,7 +642,7 @@
<< "': " << result.error();
}
} else {
- stop_first.push_back(s.get());
+ stop_first.insert(s->name());
}
}
@@ -703,7 +706,7 @@
LOG(INFO) << "vold not running, skipping vold shutdown";
}
// logcat stopped here
- StopServices(GetDebuggingServices(false /* only_post_data */), 0ms, false /* SIGKILL */);
+ StopServices(kDebuggingServices, 0ms, false /* SIGKILL */);
// 4. sync, try umount, and optionally run fsck for user shutdown
{
Timer sync_timer;
@@ -785,17 +788,17 @@
sub_reason = "resetprop";
return Error() << "Failed to reset sys.powerctl property";
}
- std::vector<Service*> stop_first;
+ std::set<std::string> stop_first;
// Remember the services that were enabled. We will need to manually enable them again otherwise
// triggers like class_start won't restart them.
- std::vector<Service*> were_enabled;
- stop_first.reserve(ServiceList::GetInstance().services().size());
+ std::set<std::string> were_enabled;
for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
if (s->is_post_data() && !kDebuggingServices.count(s->name())) {
- stop_first.push_back(s);
+ stop_first.insert(s->name());
}
+ // TODO(ioffe): we should also filter out temporary services here.
if (s->is_post_data() && s->IsEnabled()) {
- were_enabled.push_back(s);
+ were_enabled.insert(s->name());
}
}
{
@@ -815,8 +818,8 @@
r > 0) {
auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666)));
android::base::WriteStringToFd("Post-data services still running: \n", fd);
- for (const auto& s : stop_first) {
- if (s->IsRunning()) {
+ for (const auto& s : ServiceList::GetInstance()) {
+ if (s->IsRunning() && stop_first.count(s->name())) {
android::base::WriteStringToFd(s->name() + "\n", fd);
}
}
@@ -831,13 +834,14 @@
sub_reason = "vold_reset";
return result;
}
- if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */),
- sigkill_timeout, false /* SIGKILL */);
+ const auto& debugging_services = GetPostDataDebuggingServices();
+ if (int r = StopServicesAndLogViolations(debugging_services, sigkill_timeout,
+ false /* SIGKILL */);
r > 0) {
auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666)));
android::base::WriteStringToFd("Debugging services still running: \n", fd);
- for (const auto& s : GetDebuggingServices(true)) {
- if (s->IsRunning()) {
+ for (const auto& s : ServiceList::GetInstance()) {
+ if (s->IsRunning() && debugging_services.count(s->name())) {
android::base::WriteStringToFd(s->name() + "\n", fd);
}
}
@@ -867,9 +871,11 @@
return false;
});
// Re-enable services
- for (const auto& s : were_enabled) {
- LOG(INFO) << "Re-enabling service '" << s->name() << "'";
- s->Enable();
+ for (const auto& s : ServiceList::GetInstance()) {
+ if (were_enabled.count(s->name())) {
+ LOG(INFO) << "Re-enabling service '" << s->name() << "'";
+ s->Enable();
+ }
}
ServiceList::GetInstance().ResetState();
LeaveShutdown();
diff --git a/init/security.cpp b/init/security.cpp
index ac784a3..970696e 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -36,59 +36,6 @@
namespace android {
namespace init {
-// Writes 512 bytes of output from Hardware RNG (/dev/hw_random, backed
-// by Linux kernel's hw_random framework) into Linux RNG's via /dev/urandom.
-// Does nothing if Hardware RNG is not present.
-//
-// Since we don't yet trust the quality of Hardware RNG, these bytes are not
-// mixed into the primary pool of Linux RNG and the entropy estimate is left
-// unmodified.
-//
-// If the HW RNG device /dev/hw_random is present, we require that at least
-// 512 bytes read from it are written into Linux RNG. QA is expected to catch
-// devices/configurations where these I/O operations are blocking for a long
-// time. We do not reboot or halt on failures, as this is a best-effort
-// attempt.
-Result<void> MixHwrngIntoLinuxRngAction(const BuiltinArguments&) {
- unique_fd hwrandom_fd(
- TEMP_FAILURE_RETRY(open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC)));
- if (hwrandom_fd == -1) {
- if (errno == ENOENT) {
- LOG(INFO) << "/dev/hw_random not found";
- // It's not an error to not have a Hardware RNG.
- return {};
- }
- return ErrnoError() << "Failed to open /dev/hw_random";
- }
-
- unique_fd urandom_fd(
- TEMP_FAILURE_RETRY(open("/dev/urandom", O_WRONLY | O_NOFOLLOW | O_CLOEXEC)));
- if (urandom_fd == -1) {
- return ErrnoError() << "Failed to open /dev/urandom";
- }
-
- char buf[512];
- size_t total_bytes_written = 0;
- while (total_bytes_written < sizeof(buf)) {
- ssize_t chunk_size =
- TEMP_FAILURE_RETRY(read(hwrandom_fd, buf, sizeof(buf) - total_bytes_written));
- if (chunk_size == -1) {
- return ErrnoError() << "Failed to read from /dev/hw_random";
- } else if (chunk_size == 0) {
- return Error() << "Failed to read from /dev/hw_random: EOF";
- }
-
- chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size));
- if (chunk_size == -1) {
- return ErrnoError() << "Failed to write to /dev/urandom";
- }
- total_bytes_written += chunk_size;
- }
-
- LOG(INFO) << "Mixed " << total_bytes_written << " bytes from /dev/hw_random into /dev/urandom";
- return {};
-}
-
static bool SetHighestAvailableOptionValue(const std::string& path, int min, int max) {
std::ifstream inf(path, std::fstream::in);
if (!inf) {
diff --git a/init/security.h b/init/security.h
index 43c2739..e8bec6a 100644
--- a/init/security.h
+++ b/init/security.h
@@ -26,7 +26,6 @@
namespace android {
namespace init {
-Result<void> MixHwrngIntoLinuxRngAction(const BuiltinArguments&);
Result<void> SetMmapRndBitsAction(const BuiltinArguments&);
Result<void> SetKptrRestrictAction(const BuiltinArguments&);
Result<void> TestPerfEventSelinuxAction(const BuiltinArguments&);
diff --git a/init/service.cpp b/init/service.cpp
index f6ce094..cfb8284 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -127,8 +127,7 @@
static bool AreRuntimeApexesReady() {
struct stat buf;
- return stat("/apex/com.android.art/", &buf) == 0 &&
- stat("/apex/com.android.runtime/", &buf) == 0;
+ return stat("/apex/com.android.runtime/", &buf) == 0;
}
unsigned long Service::next_start_order_ = 1;
diff --git a/init/service_list.h b/init/service_list.h
index 3b9018b..555da25 100644
--- a/init/service_list.h
+++ b/init/service_list.h
@@ -66,7 +66,6 @@
auto begin() const { return services_.begin(); }
auto end() const { return services_.end(); }
- const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
const std::vector<Service*> services_in_shutdown_order() const;
void MarkPostData();
diff --git a/init/sysprop/Android.bp b/init/sysprop/Android.bp
index 7582875..296cdc1 100644
--- a/init/sysprop/Android.bp
+++ b/init/sysprop/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_init_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_core_init_license"],
+}
+
sysprop_library {
name: "com.android.sysprop.init",
srcs: ["InitProperties.sysprop"],
diff --git a/init/test_kill_services/Android.bp b/init/test_kill_services/Android.bp
index d59e548..37361a8 100644
--- a/init/test_kill_services/Android.bp
+++ b/init/test_kill_services/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_init_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_core_init_license"],
+}
+
cc_test {
name: "init_kill_services_test",
srcs: ["init_kill_services_test.cpp"],
diff --git a/init/test_service/Android.bp b/init/test_service/Android.bp
index 8bd16a7..37bc371 100644
--- a/init/test_service/Android.bp
+++ b/init/test_service/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_init_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_core_init_license"],
+}
+
cc_binary {
name: "test_service",
srcs: ["test_service.cpp"],
diff --git a/init/test_utils/service_utils.cpp b/init/test_utils/service_utils.cpp
index ae68679..6426ed9 100644
--- a/init/test_utils/service_utils.cpp
+++ b/init/test_utils/service_utils.cpp
@@ -44,7 +44,7 @@
}
ServiceInterfacesMap result;
- for (const auto& service : service_list.services()) {
+ for (const auto& service : service_list) {
// Create an entry for all services, including services that may not
// have any declared interfaces.
result[service->name()] = service->interfaces();
diff --git a/init/util.cpp b/init/util.cpp
index 255434a..e69b43f 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -246,6 +246,19 @@
}
}
+void ImportBootconfig(const std::function<void(const std::string&, const std::string&)>& fn) {
+ std::string bootconfig;
+ android::base::ReadFileToString("/proc/bootconfig", &bootconfig);
+
+ for (const auto& entry : android::base::Split(bootconfig, "\n")) {
+ std::vector<std::string> pieces = android::base::Split(entry, "=");
+ if (pieces.size() == 2) {
+ pieces[1].erase(std::remove(pieces[1].begin(), pieces[1].end(), '"'), pieces[1].end());
+ fn(android::base::Trim(pieces[0]), android::base::Trim(pieces[1]));
+ }
+ }
+}
+
bool make_dir(const std::string& path, mode_t mode) {
std::string secontext;
if (SelabelLookupFileContext(path, mode, &secontext) && !secontext.empty()) {
diff --git a/init/util.h b/init/util.h
index 3cdc9f4..7745d77 100644
--- a/init/util.h
+++ b/init/util.h
@@ -55,6 +55,7 @@
bool mkdir_recursive(const std::string& pathname, mode_t mode);
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
void ImportKernelCmdline(const std::function<void(const std::string&, const std::string&)>&);
+void ImportBootconfig(const std::function<void(const std::string&, const std::string&)>&);
bool make_dir(const std::string& path, mode_t mode);
bool is_dir(const char* pathname);
Result<std::string> ExpandProps(const std::string& src);
diff --git a/libappfuse/Android.bp b/libappfuse/Android.bp
index ae1481f..a9bd94e 100644
--- a/libappfuse/Android.bp
+++ b/libappfuse/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2016 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libappfuse_defaults",
local_include_dirs: ["include"],
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 44e7933..692e223 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libasyncio_defaults",
cflags: [
diff --git a/libbinderwrapper/Android.bp b/libbinderwrapper/Android.bp
index d2487e2..75f43ee 100644
--- a/libbinderwrapper/Android.bp
+++ b/libbinderwrapper/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libbinderwrapper_defaults",
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index 923b291..b33d46d 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libcrypto_utils",
vendor_available: true,
diff --git a/libcrypto_utils/tests/Android.bp b/libcrypto_utils/tests/Android.bp
index 5aadfe2..087e83b 100644
--- a/libcrypto_utils/tests/Android.bp
+++ b/libcrypto_utils/tests/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test_host {
name: "libcrypto_utils_test",
srcs: ["android_pubkey_test.cpp"],
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index c75e538..0d9f2c7 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -1,48 +1,51 @@
-//
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+package {
+ default_applicable_licenses: ["system_core_libcutils_license"],
+}
+
+license {
+ name: "system_core_libcutils_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-MIT", // strlcpy.c
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
filegroup {
name: "android_filesystem_config_header",
srcs: ["include/private/android_filesystem_config.h"],
}
-// some files must not be compiled when building against Mingw
-// they correspond to features not used by our host development tools
-// which are also hard or even impossible to port to native Win32
-libcutils_nonwindows_sources = [
- "fs.cpp",
- "hashmap.cpp",
- "multiuser.cpp",
- "str_parms.cpp",
-]
+cc_defaults {
+ name: "libcutils_defaults",
+ cflags: [
+ "-Wno-exit-time-destructors",
+ ],
-cc_library_headers {
- name: "libcutils_headers",
- vendor_available: true,
product_available: true,
- recovery_available: true,
ramdisk_available: true,
+ recovery_available: true,
+ vendor_available: true,
vendor_ramdisk_available: true,
+
host_supported: true,
+ native_bridge_supported: true,
+
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
],
min_sdk_version: "29",
- native_bridge_supported: true,
+}
+
+cc_library_headers {
+ name: "libcutils_headers",
+ defaults: ["libcutils_defaults"],
+
export_include_dirs: ["include"],
target: {
vendor: {
@@ -63,18 +66,7 @@
// Socket specific parts of libcutils that are safe to statically link into an APEX.
cc_library {
name: "libcutils_sockets",
- vendor_available: true,
- product_available: true,
- recovery_available: true,
- ramdisk_available: true,
- vendor_ramdisk_available: true,
- host_supported: true,
- native_bridge_supported: true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- min_sdk_version: "29",
+ defaults: ["libcutils_defaults"],
export_include_dirs: ["include"],
@@ -145,23 +137,23 @@
},
}
+// some files must not be compiled when building against Mingw
+// they correspond to features not used by our host development tools
+// which are also hard or even impossible to port to native Win32
+libcutils_nonwindows_sources = [
+ "fs.cpp",
+ "hashmap.cpp",
+ "multiuser.cpp",
+ "str_parms.cpp",
+]
+
cc_library {
name: "libcutils",
- vendor_available: true,
- product_available: true,
+ defaults: ["libcutils_defaults"],
vndk: {
enabled: true,
support_system_process: true,
},
- recovery_available: true,
- vendor_ramdisk_available: true,
- host_supported: true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- min_sdk_version: "29",
- native_bridge_supported: true,
srcs: [
"config_utils.cpp",
"canned_fs_config.cpp",
@@ -259,7 +251,6 @@
header_libs: [
"libbase_headers",
"libcutils_headers",
- "libutils_headers",
"libprocessgroup_headers",
],
export_header_lib_headers: [
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 79c3abc..54eeeac 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -37,7 +37,6 @@
#include <android-base/strings.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
-#include <utils/Compat.h>
#include "fs_config.h"
diff --git a/libcutils/include/cutils/threads.h b/libcutils/include/cutils/threads.h
index 0f7f8a8..0082c6c 100644
--- a/libcutils/include/cutils/threads.h
+++ b/libcutils/include/cutils/threads.h
@@ -31,7 +31,9 @@
//
// Deprecated: use android::base::GetThreadId instead, which doesn't truncate on Mac/Windows.
//
+#if !defined(__GLIBC__) || __GLIBC__ >= 2 && __GLIBC_MINOR__ < 32
extern pid_t gettid();
+#endif
#ifdef __cplusplus
}
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index 793e2ce..ef426ff 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -104,14 +104,6 @@
void atrace_update_tags();
/**
- * Set whether the process is debuggable. By default the process is not
- * considered debuggable. If the process is not debuggable then application-
- * level tracing is not allowed unless the ro.debuggable system property is
- * set to '1'.
- */
-void atrace_set_debuggable(bool debuggable);
-
-/**
* Set whether tracing is enabled for the current process. This is used to
* prevent tracing within the Zygote process.
*/
diff --git a/libcutils/threads.cpp b/libcutils/threads.cpp
index 8cfee1e..6ece7a3 100644
--- a/libcutils/threads.cpp
+++ b/libcutils/threads.cpp
@@ -25,8 +25,9 @@
#include <windows.h>
#endif
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(__GLIBC__) && __GLIBC_MINOR__ >= 32
// No definition needed for Android because we'll just pick up bionic's copy.
+// No definition needed for Glibc >= 2.32 because it exposes its own copy.
#else
pid_t gettid() {
#if defined(__APPLE__)
diff --git a/libcutils/trace-dev.inc b/libcutils/trace-dev.inc
index 6543426..3b459e0 100644
--- a/libcutils/trace-dev.inc
+++ b/libcutils/trace-dev.inc
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <fnmatch.h>
#include <limits.h>
#include <pthread.h>
#include <stdatomic.h>
@@ -51,7 +52,6 @@
atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(false);
int atrace_marker_fd = -1;
uint64_t atrace_enabled_tags = ATRACE_TAG_NOT_READY;
-static bool atrace_is_debuggable = false;
static atomic_bool atrace_is_enabled = ATOMIC_VAR_INIT(true);
static pthread_mutex_t atrace_tags_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -95,15 +95,6 @@
return atrace_enabled_tags;
}
-// Set whether this process is debuggable, which determines whether
-// application-level tracing is allowed when the ro.debuggable system property
-// is not set to '1'.
-void atrace_set_debuggable(bool debuggable)
-{
- atrace_is_debuggable = debuggable;
- atrace_update_tags();
-}
-
// Check whether the given command line matches one of the comma-separated
// values listed in the app_cmdlines property.
static bool atrace_is_cmdline_match(const char* cmdline)
@@ -116,7 +107,7 @@
for (int i = 0; i < count; i++) {
snprintf(buf, sizeof(buf), "debug.atrace.app_%d", i);
property_get(buf, value, "");
- if (strcmp(value, "*") == 0 || strcmp(value, cmdline) == 0) {
+ if (fnmatch(value, cmdline, FNM_NOESCAPE) == 0) {
return true;
}
}
@@ -127,24 +118,21 @@
// Determine whether application-level tracing is enabled for this process.
static bool atrace_is_app_tracing_enabled()
{
- bool sys_debuggable = property_get_bool("ro.debuggable", 0);
bool result = false;
- if (sys_debuggable || atrace_is_debuggable) {
- // Check whether tracing is enabled for this process.
- FILE * file = fopen("/proc/self/cmdline", "re");
- if (file) {
- char cmdline[4096];
- if (fgets(cmdline, sizeof(cmdline), file)) {
- result = atrace_is_cmdline_match(cmdline);
- } else {
- ALOGE("Error reading cmdline: %s (%d)", strerror(errno), errno);
- }
- fclose(file);
+ // Check whether tracing is enabled for this process.
+ FILE * file = fopen("/proc/self/cmdline", "re");
+ if (file) {
+ char cmdline[4096];
+ if (fgets(cmdline, sizeof(cmdline), file)) {
+ result = atrace_is_cmdline_match(cmdline);
} else {
- ALOGE("Error opening /proc/self/cmdline: %s (%d)", strerror(errno),
- errno);
+ ALOGE("Error reading cmdline: %s (%d)", strerror(errno), errno);
}
+ fclose(file);
+ } else {
+ ALOGE("Error opening /proc/self/cmdline: %s (%d)", strerror(errno),
+ errno);
}
return result;
diff --git a/libdiskconfig/Android.bp b/libdiskconfig/Android.bp
index b92f086..a3d643e 100644
--- a/libdiskconfig/Android.bp
+++ b/libdiskconfig/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libdiskconfig",
vendor_available: true,
diff --git a/libgrallocusage/Android.bp b/libgrallocusage/Android.bp
index 33ae13d..f31b5f1 100644
--- a/libgrallocusage/Android.bp
+++ b/libgrallocusage/Android.bp
@@ -12,6 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["system_core_libgrallocusage_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_libgrallocusage_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_library {
name: "libgrallocusage",
vendor_available: true,
diff --git a/libgrallocusage/OWNERS b/libgrallocusage/OWNERS
index 154dc6d..de2bf16 100644
--- a/libgrallocusage/OWNERS
+++ b/libgrallocusage/OWNERS
@@ -1,3 +1,2 @@
-jessehall@google.com
-olv@google.com
-stoza@google.com
+jreck@google.com
+lpy@google.com
diff --git a/libkeyutils/Android.bp b/libkeyutils/Android.bp
index b388e95..9848cd8 100644
--- a/libkeyutils/Android.bp
+++ b/libkeyutils/Android.bp
@@ -1,3 +1,31 @@
+package {
+ default_applicable_licenses: ["system_core_libkeyutils_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "system_core_libkeyutils_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
cc_library {
name: "libkeyutils",
cflags: ["-Werror"],
diff --git a/libkeyutils/mini_keyctl/Android.bp b/libkeyutils/mini_keyctl/Android.bp
index a04a3db..417ddac 100644
--- a/libkeyutils/mini_keyctl/Android.bp
+++ b/libkeyutils/mini_keyctl/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libmini_keyctl_static",
srcs: [
diff --git a/libmodprobe/Android.bp b/libmodprobe/Android.bp
index 78da46c..ba11dc9 100644
--- a/libmodprobe/Android.bp
+++ b/libmodprobe/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libmodprobe",
cflags: [
diff --git a/libnetutils/Android.bp b/libnetutils/Android.bp
index eec2415..2864ad0 100644
--- a/libnetutils/Android.bp
+++ b/libnetutils/Android.bp
@@ -1,3 +1,20 @@
+package {
+ default_applicable_licenses: ["system_core_libnetutils_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_libnetutils_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_library_shared {
name: "libnetutils",
vendor_available: true,
diff --git a/libpackagelistparser/Android.bp b/libpackagelistparser/Android.bp
index c3f8692..81885d7 100644
--- a/libpackagelistparser/Android.bp
+++ b/libpackagelistparser/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libpackagelistparser",
ramdisk_available: true,
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index f104100..c68552d 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libprocessgroup_headers",
vendor_available: true,
diff --git a/libprocessgroup/cgrouprc/Android.bp b/libprocessgroup/cgrouprc/Android.bp
index bb59942..0cbe0cc 100644
--- a/libprocessgroup/cgrouprc/Android.bp
+++ b/libprocessgroup/cgrouprc/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libcgrouprc",
host_supported: true,
@@ -46,19 +50,19 @@
"libcgrouprc_format",
],
stubs: {
- symbol_file: "libcgrouprc.llndk.txt",
+ symbol_file: "libcgrouprc.map.txt",
versions: ["29"],
},
target: {
linux: {
- version_script: "libcgrouprc.llndk.txt",
+ version_script: "libcgrouprc.map.txt",
},
},
}
llndk_library {
name: "libcgrouprc.llndk",
- symbol_file: "libcgrouprc.llndk.txt",
+ symbol_file: "libcgrouprc.map.txt",
native_bridge_supported: true,
export_include_dirs: [
"include",
diff --git a/libprocessgroup/cgrouprc/libcgrouprc.llndk.txt b/libprocessgroup/cgrouprc/libcgrouprc.map.txt
similarity index 100%
rename from libprocessgroup/cgrouprc/libcgrouprc.llndk.txt
rename to libprocessgroup/cgrouprc/libcgrouprc.map.txt
diff --git a/libprocessgroup/cgrouprc_format/Android.bp b/libprocessgroup/cgrouprc_format/Android.bp
index 6428930..0590924 100644
--- a/libprocessgroup/cgrouprc_format/Android.bp
+++ b/libprocessgroup/cgrouprc_format/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libcgrouprc_format",
host_supported: true,
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 4aa439a..fa2642d 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -65,6 +65,10 @@
void removeAllProcessGroups(void);
+// Provides the path for an attribute in a specific process group
+// Returns false in case of error, true in case of success
+bool getAttributePathForTask(const std::string& attr_name, int tid, std::string* path);
+
#endif // __ANDROID_VNDK__
__END_DECLS
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 2bf48fc..815d2bb 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -421,14 +421,27 @@
static int createProcessGroupInternal(uid_t uid, int initialPid, std::string cgroup) {
auto uid_path = ConvertUidToPath(cgroup.c_str(), uid);
- if (!MkdirAndChown(uid_path, 0750, AID_SYSTEM, AID_SYSTEM)) {
+ struct stat cgroup_stat;
+ mode_t cgroup_mode = 0750;
+ gid_t cgroup_uid = AID_SYSTEM;
+ uid_t cgroup_gid = AID_SYSTEM;
+
+ if (stat(cgroup.c_str(), &cgroup_stat) == 1) {
+ PLOG(ERROR) << "Failed to get stats for " << cgroup;
+ } else {
+ cgroup_mode = cgroup_stat.st_mode;
+ cgroup_uid = cgroup_stat.st_uid;
+ cgroup_gid = cgroup_stat.st_gid;
+ }
+
+ if (!MkdirAndChown(uid_path, cgroup_mode, cgroup_uid, cgroup_gid)) {
PLOG(ERROR) << "Failed to make and chown " << uid_path;
return -errno;
}
auto uid_pid_path = ConvertUidPidToPath(cgroup.c_str(), uid, initialPid);
- if (!MkdirAndChown(uid_pid_path, 0750, AID_SYSTEM, AID_SYSTEM)) {
+ if (!MkdirAndChown(uid_pid_path, cgroup_mode, cgroup_uid, cgroup_gid)) {
PLOG(ERROR) << "Failed to make and chown " << uid_pid_path;
return -errno;
}
@@ -495,3 +508,7 @@
bool setProcessGroupLimit(uid_t, int pid, int64_t limit_in_bytes) {
return SetProcessGroupValue(pid, "MemLimit", limit_in_bytes);
}
+
+bool getAttributePathForTask(const std::string& attr_name, int tid, std::string* path) {
+ return CgroupGetAttributePathForTask(attr_name, tid, path);
+}
diff --git a/libprocessgroup/profiles/Android.bp b/libprocessgroup/profiles/Android.bp
index a496237..885971a 100644
--- a/libprocessgroup/profiles/Android.bp
+++ b/libprocessgroup/profiles/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
prebuilt_etc {
name: "cgroups.json",
src: "cgroups.json",
@@ -123,9 +127,6 @@
"cgroups.recovery.json",
"task_profiles.json",
],
- test_suites: [
- "general-tests",
- ],
}
cc_test {
diff --git a/libprocessgroup/profiles/TEST_MAPPING b/libprocessgroup/profiles/TEST_MAPPING
deleted file mode 100644
index 5ff4112..0000000
--- a/libprocessgroup/profiles/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "presubmit": [
- {
- "name": "libprocessgroup_proto_test",
- "host": true
- }
- ]
-}
diff --git a/libprocessgroup/profiles/cgroups.recovery.json b/libprocessgroup/profiles/cgroups.recovery.json
index 2c63c08..e275252 100644
--- a/libprocessgroup/profiles/cgroups.recovery.json
+++ b/libprocessgroup/profiles/cgroups.recovery.json
@@ -1,2 +1,8 @@
{
+ "Cgroups2": {
+ "Path": "/sys/fs/cgroup",
+ "Mode": "0755",
+ "UID": "root",
+ "GID": "root"
+ }
}
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 628098b..5b57bdd 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -46,7 +46,7 @@
"File": "cpu.uclamp.latency_sensitive"
},
{
- "Name": "Freezer",
+ "Name": "FreezerState",
"Controller": "freezer",
"File": "cgroup.freeze"
}
@@ -70,11 +70,11 @@
"Name": "Frozen",
"Actions": [
{
- "Name": "SetAttribute",
+ "Name": "JoinCgroup",
"Params":
{
- "Name": "Freezer",
- "Value": "1"
+ "Controller": "freezer",
+ "Path": ""
}
}
]
@@ -83,11 +83,11 @@
"Name": "Unfrozen",
"Actions": [
{
- "Name": "SetAttribute",
+ "Name": "JoinCgroup",
"Params":
{
- "Name": "Freezer",
- "Value": "0"
+ "Controller": "freezer",
+ "Path": "../"
}
}
]
diff --git a/libprocessgroup/setup/Android.bp b/libprocessgroup/setup/Android.bp
index f6fc066..ea6c247 100644
--- a/libprocessgroup/setup/Android.bp
+++ b/libprocessgroup/setup/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_shared {
name: "libprocessgroup_setup",
recovery_available: true,
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 753fd2d..aa41acb 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -183,10 +183,12 @@
return false;
}
- Json::Reader reader;
+ Json::CharReaderBuilder builder;
+ std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
- if (!reader.parse(json_doc, root)) {
- LOG(ERROR) << "Failed to parse cgroups description: " << reader.getFormattedErrorMessages();
+ std::string errorMessage;
+ if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+ LOG(ERROR) << "Failed to parse cgroups description: " << errorMessage;
return false;
}
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 8d4ce25..f13a681 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -425,10 +425,12 @@
return false;
}
- Json::Reader reader;
+ Json::CharReaderBuilder builder;
+ std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
- if (!reader.parse(json_doc, root)) {
- LOG(ERROR) << "Failed to parse task profiles: " << reader.getFormattedErrorMessages();
+ std::string errorMessage;
+ if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+ LOG(ERROR) << "Failed to parse task profiles: " << errorMessage;
return false;
}
diff --git a/libqtaguid/Android.bp b/libqtaguid/Android.bp
index de632ca..64db095 100644
--- a/libqtaguid/Android.bp
+++ b/libqtaguid/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libqtaguid_headers",
vendor_available: false,
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index 5b6ce41..0b4b640 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2010 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libsparse",
host_supported: true,
diff --git a/libstats/push_compat/Android.bp b/libstats/push_compat/Android.bp
index 43ae69d..4b2f40e 100644
--- a/libstats/push_compat/Android.bp
+++ b/libstats/push_compat/Android.bp
@@ -19,6 +19,10 @@
// protocols. This library should only be used by DNS resolver or other
// native modules on Q that log pushed atoms to statsd.
// =========================================================================
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libstatspush_compat_defaults",
srcs: [
@@ -65,4 +69,3 @@
],
static_libs: ["libgmock"],
}
-
diff --git a/libsuspend/Android.bp b/libsuspend/Android.bp
index c5f1f5e..671de4d 100644
--- a/libsuspend/Android.bp
+++ b/libsuspend/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2012 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libsuspend",
srcs: [
diff --git a/libsync/Android.bp b/libsync/Android.bp
index 4828892..540a246 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -1,3 +1,20 @@
+package {
+ default_applicable_licenses: ["system_core_libsync_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_libsync_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
ndk_headers {
name: "libsync_headers",
from: "include/ndk",
diff --git a/libsystem/Android.bp b/libsystem/Android.bp
index b37b8ec..dacc8ca 100644
--- a/libsystem/Android.bp
+++ b/libsystem/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "libsystem_headers",
vendor_available: true,
diff --git a/libsystem/OWNERS b/libsystem/OWNERS
index 4f800d4..9bda04c 100644
--- a/libsystem/OWNERS
+++ b/libsystem/OWNERS
@@ -1,8 +1,6 @@
# graphics/composer
adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
# camera
etalvala@google.com
diff --git a/libsysutils/Android.bp b/libsysutils/Android.bp
index 3b98bab..5f472b2 100644
--- a/libsysutils/Android.bp
+++ b/libsysutils/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libsysutils",
vendor_available: true,
diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp
index fc6f305..3883317 100644
--- a/libusbhost/Android.bp
+++ b/libusbhost/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libusbhost",
vendor_available: true,
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 1e7cbdb..6201569 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -1,16 +1,17 @@
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+package {
+ default_applicable_licenses: ["system_core_libutils_license"],
+}
+
+license {
+ name: "system_core_libutils_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
cc_library_headers {
name: "libutils_headers",
@@ -74,6 +75,7 @@
cflags: [
"-Wall",
"-Werror",
+ "-Wno-exit-time-destructors",
],
header_libs: [
"libbase_headers",
diff --git a/libutils/include/utils/SystemClock.h b/libutils/include/utils/SystemClock.h
index 892104c..3c59297 100644
--- a/libutils/include/utils/SystemClock.h
+++ b/libutils/include/utils/SystemClock.h
@@ -20,11 +20,18 @@
#include <stdint.h>
#include <sys/types.h>
+// See https://developer.android.com/reference/android/os/SystemClock
+// to learn more about Android's timekeeping facilities.
+
namespace android {
+// Returns milliseconds since boot, not counting time spent in deep sleep.
int64_t uptimeMillis();
+// Returns nanoseconds since boot, not counting time spent in deep sleep.
int64_t uptimeNanos();
+// Returns milliseconds since boot, including time spent in sleep.
int64_t elapsedRealtime();
+// Returns nanoseconds since boot, including time spent in sleep.
int64_t elapsedRealtimeNano();
} // namespace android
diff --git a/libvndksupport/Android.bp b/libvndksupport/Android.bp
index a5cece4..11c75f7 100644
--- a/libvndksupport/Android.bp
+++ b/libvndksupport/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libvndksupport",
native_bridge_supported: true,
diff --git a/libvndksupport/tests/Android.bp b/libvndksupport/tests/Android.bp
index 2570cce..ba700cb 100644
--- a/libvndksupport/tests/Android.bp
+++ b/libvndksupport/tests/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "libvndksupport-tests",
srcs: [
diff --git a/llkd/Android.bp b/llkd/Android.bp
index 62a637d..1c0e0f0 100644
--- a/llkd/Android.bp
+++ b/llkd/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "llkd_headers",
diff --git a/llkd/tests/Android.bp b/llkd/tests/Android.bp
index 6dd5938..3db6e85 100644
--- a/llkd/tests/Android.bp
+++ b/llkd/tests/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "llkd_unit_test",
diff --git a/property_service/libpropertyinfoparser/Android.bp b/property_service/libpropertyinfoparser/Android.bp
index 2d7e9cb..6861456 100644
--- a/property_service/libpropertyinfoparser/Android.bp
+++ b/property_service/libpropertyinfoparser/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libpropertyinfoparser",
host_supported: true,
@@ -8,7 +12,6 @@
native_bridge_supported: true,
srcs: ["property_info_parser.cpp"],
- cpp_std: "experimental",
cppflags: [
"-Wall",
"-Wextra",
diff --git a/property_service/libpropertyinfoserializer/Android.bp b/property_service/libpropertyinfoserializer/Android.bp
index aa02a3a..f260450 100644
--- a/property_service/libpropertyinfoserializer/Android.bp
+++ b/property_service/libpropertyinfoserializer/Android.bp
@@ -1,7 +1,10 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "propertyinfoserializer_defaults",
host_supported: true,
- cpp_std: "experimental",
cppflags: [
"-Wall",
"-Wextra",
diff --git a/property_service/property_info_checker/Android.bp b/property_service/property_info_checker/Android.bp
index 65e660a..d26e359 100644
--- a/property_service/property_info_checker/Android.bp
+++ b/property_service/property_info_checker/Android.bp
@@ -1,8 +1,11 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "property_info_checker",
host_supported: true,
static_executable: true,
- cpp_std: "experimental",
static_libs: [
"libpropertyinfoserializer",
"libpropertyinfoparser",
diff --git a/qemu_pipe/Android.bp b/qemu_pipe/Android.bp
index ad86a4e..42a69db 100644
--- a/qemu_pipe/Android.bp
+++ b/qemu_pipe/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2011 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libqemu_pipe",
vendor_available: true,
diff --git a/reboot/Android.bp b/reboot/Android.bp
index cc71723..7b243bd 100644
--- a/reboot/Android.bp
+++ b/reboot/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2013 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "reboot",
srcs: ["reboot.c"],
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index d63868a..6a80808 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
prebuilt_etc {
name: "init.rc",
src: "init.rc",
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 73d1101..5503cc1 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -5,6 +5,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init-debug.rc
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/init
@@ -18,6 +20,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := asan.options
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(TARGET_OUT)
@@ -29,6 +33,8 @@
ifeq ($(SANITIZE_TARGET_SYSTEM),true)
include $(CLEAR_VARS)
LOCAL_MODULE:= asan_extract
+LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS:= notice
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := asan_extract.sh
@@ -47,7 +53,10 @@
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE := init.environ.rc
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+LOCAL_REQUIRED_MODULES := etc_classpath
EXPORT_GLOBAL_ASAN_OPTIONS :=
ifneq ($(filter address,$(SANITIZE_TARGET)),)
@@ -163,9 +172,7 @@
$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in
@echo "Generate: $< -> $@"
@mkdir -p $(dir $@)
- $(hide) sed -e 's?%BOOTCLASSPATH%?$(PRODUCT_BOOTCLASSPATH)?g' $< >$@
- $(hide) sed -i -e 's?%DEX2OATBOOTCLASSPATH%?$(PRODUCT_DEX2OAT_BOOTCLASSPATH)?g' $@
- $(hide) sed -i -e 's?%SYSTEMSERVERCLASSPATH%?$(PRODUCT_SYSTEM_SERVER_CLASSPATH)?g' $@
+ $(hide) cp $< $@
$(hide) sed -i -e 's?%EXPORT_GLOBAL_ASAN_OPTIONS%?$(EXPORT_GLOBAL_ASAN_OPTIONS)?g' $@
$(hide) sed -i -e 's?%EXPORT_GLOBAL_GCOV_OPTIONS%?$(EXPORT_GLOBAL_GCOV_OPTIONS)?g' $@
$(hide) sed -i -e 's?%EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS%?$(EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS)?g' $@
@@ -179,9 +186,26 @@
endef
#######################################
+# /etc/classpath
+include $(CLEAR_VARS)
+LOCAL_MODULE := etc_classpath
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_MODULE_STEM := classpath
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE):
+ @echo "Generate: $@"
+ @mkdir -p $(dir $@)
+ $(hide) echo "export BOOTCLASSPATH $(PRODUCT_BOOTCLASSPATH)" > $@
+ $(hide) echo "export DEX2OATBOOTCLASSPATH $(PRODUCT_DEX2OAT_BOOTCLASSPATH)" >> $@
+ $(hide) echo "export SYSTEMSERVERCLASSPATH $(PRODUCT_SYSTEM_SERVER_CLASSPATH)" >> $@
+
+#######################################
# sanitizer.libraries.txt
include $(CLEAR_VARS)
LOCAL_MODULE := sanitizer.libraries.txt
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
@@ -206,6 +230,8 @@
# adb_debug.prop in debug ramdisk
include $(CLEAR_VARS)
LOCAL_MODULE := adb_debug.prop
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_DEBUG_RAMDISK_OUT)
diff --git a/rootdir/avb/Android.bp b/rootdir/avb/Android.bp
index 8c7caf3..cfc59a7 100644
--- a/rootdir/avb/Android.bp
+++ b/rootdir/avb/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
filegroup {
name: "q-gsi_avbpubkey",
srcs: [
diff --git a/rootdir/avb/Android.mk b/rootdir/avb/Android.mk
index f71f205..647cfa2 100644
--- a/rootdir/avb/Android.mk
+++ b/rootdir/avb/Android.mk
@@ -19,6 +19,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := q-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -30,6 +32,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := q-developer-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -41,6 +45,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := r-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -52,6 +58,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := r-developer-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -63,6 +71,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := s-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -74,6 +84,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := s-developer-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
@@ -85,6 +97,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE := qcar-gsi.avbpubkey
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_PATH := $(my_gsi_avb_keys_path)
diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
index fdaaf1a..bf6e986 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -10,9 +10,6 @@
export ANDROID_TZDATA_ROOT /apex/com.android.tzdata
export EXTERNAL_STORAGE /sdcard
export ASEC_MOUNTPOINT /mnt/asec
- export BOOTCLASSPATH %BOOTCLASSPATH%
- export DEX2OATBOOTCLASSPATH %DEX2OATBOOTCLASSPATH%
- export SYSTEMSERVERCLASSPATH %SYSTEMSERVERCLASSPATH%
%EXPORT_GLOBAL_ASAN_OPTIONS%
%EXPORT_GLOBAL_GCOV_OPTIONS%
%EXPORT_GLOBAL_CLANG_COVERAGE_OPTIONS%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 03af4f3..0e1e98b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -244,6 +244,7 @@
chmod 0664 /dev/blkio/background/tasks
write /dev/blkio/blkio.weight 1000
write /dev/blkio/background/blkio.weight 200
+ write /dev/blkio/background/blkio.bfq.weight 10
write /dev/blkio/blkio.group_idle 0
write /dev/blkio/background/blkio.group_idle 0
@@ -470,6 +471,9 @@
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
start lmkd
+ # Set an initial boot level - start at 10 in case we need to add earlier ones.
+ setprop keystore.boot_level 10
+
# Start essential services.
start servicemanager
start hwservicemanager
@@ -616,6 +620,15 @@
# Load trusted keys from dm-verity protected partitions
exec -- /system/bin/fsverity_init --load-verified-keys
+ # Set up a tracing instance for system_server to monitor error_report_end events.
+ # These are sent by kernel tools like KASAN and KFENCE when a memory corruption
+ # is detected.
+ mkdir /sys/kernel/tracing/instances/bootreceiver 0700 system system
+ restorecon_recursive /sys/kernel/tracing/instances/bootreceiver
+ write /sys/kernel/tracing/instances/bootreceiver/buffer_size_kb 1
+ write /sys/kernel/tracing/instances/bootreceiver/trace_options disable_on_free
+ write /sys/kernel/tracing/instances/bootreceiver/events/error_report/error_report_end/enable 1
+
on post-fs-data
mark_post_data
@@ -655,9 +668,11 @@
mkdir /data/apex 0755 root system encryption=None
mkdir /data/apex/active 0755 root system
mkdir /data/apex/backup 0700 root system
+ mkdir /data/apex/decompressed 0700 root system encryption=Require
mkdir /data/apex/hashtree 0700 root system
mkdir /data/apex/sessions 0700 root system
mkdir /data/app-staging 0751 system system encryption=DeleteIfNecessary
+ mkdir /data/apex/ota_reserved 0700 root system encryption=Require
start apexd
# Avoid predictable entropy pool. Carry over entropy from previous boot.
@@ -722,6 +737,8 @@
mkdir /data/misc/trace 0700 root root
# create location to store surface and window trace files
mkdir /data/misc/wmtrace 0700 system system
+ # create location to store accessibility trace files
+ mkdir /data/misc/a11ytrace 0700 system system
# profile file layout
mkdir /data/misc/profiles 0771 system system
mkdir /data/misc/profiles/cur 0771 system system
@@ -735,6 +752,8 @@
mkdir /data/misc/snapshotctl_log 0755 root root
# create location to store pre-reboot information
mkdir /data/misc/prereboot 0700 system system
+ # directory used for on-device signing key blob
+ mkdir /data/misc/odsign 0700 root root
mkdir /data/preloads 0775 system system encryption=None
@@ -862,6 +881,10 @@
wait_for_prop apexd.status activated
perform_apex_config
+ # Export *CLASSPATH variables from /etc/classpath
+ # TODO(b/180105615): export from the generated file instead.
+ load_exports /etc/classpath
+
# Special-case /data/media/obb per b/64566063
mkdir /data/media 0770 media_rw media_rw encryption=None
exec - media_rw media_rw -- /system/bin/chattr +F /data/media
@@ -874,6 +897,10 @@
# Set SELinux security contexts on upgrade or policy update.
restorecon --recursive --skip-ce /data
+ # Start the on-device signing daemon, and wait for it to finish, to ensure
+ # ART artifacts are generated if needed.
+ exec_start odsign
+
# After apexes are mounted, tell keymaster early boot has ended, so it will
# stop allowing use of early-boot keys
exec - system system -- /system/bin/vdc keymaster earlyBootEnded
@@ -1169,6 +1196,8 @@
chmod 0773 /data/misc/trace
# Give reads to anyone for the window trace folder on debug builds.
chmod 0775 /data/misc/wmtrace
+ # Give reads to anyone for the accessibility trace folder on debug builds.
+ chmod 0775 /data/misc/a11ytrace
on init && property:ro.debuggable=1
start console
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index e9293b5..65e29c1 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -37,8 +37,6 @@
/dev/tty 0666 root root
/dev/random 0666 root root
/dev/urandom 0666 root root
-# Make HW RNG readable by group system to let EntropyMixer read it.
-/dev/hw_random 0440 root system
/dev/ashmem* 0666 root root
/dev/binder 0666 root root
/dev/hwbinder 0666 root root
diff --git a/run-as/Android.bp b/run-as/Android.bp
index accd07d..9baee8f 100644
--- a/run-as/Android.bp
+++ b/run-as/Android.bp
@@ -14,6 +14,23 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["system_core_run-as_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_run-as_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_binary {
name: "run-as",
srcs: [
diff --git a/sdcard/Android.bp b/sdcard/Android.bp
index c096587..10a7d16 100644
--- a/sdcard/Android.bp
+++ b/sdcard/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
srcs: ["sdcard.cpp"],
name: "sdcard",
diff --git a/set-verity-state/Android.bp b/set-verity-state/Android.bp
index da112c9..2f0cb10 100644
--- a/set-verity-state/Android.bp
+++ b/set-verity-state/Android.bp
@@ -1,5 +1,9 @@
// Copyright 2019 The Android Open Source Project
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "set-verity-state",
srcs: ["set-verity-state.cpp"],
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 5e013fe..b7d7490 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
phony {
name: "shell_and_utilities",
required: [
diff --git a/storaged/Android.bp b/storaged/Android.bp
index cc19481..ec27a08 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "storaged_defaults",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 4ca5f5a..8594ec4 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -1,3 +1,20 @@
+package {
+ default_applicable_licenses: ["system_core_toolbox_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_core_toolbox_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_defaults {
name: "toolbox_defaults",
cflags: [
@@ -19,7 +36,6 @@
cc_defaults {
name: "toolbox_binary_defaults",
defaults: ["toolbox_defaults"],
- cpp_std: "experimental",
srcs: [
"toolbox.c",
"getevent.c",
diff --git a/trusty/Android.bp b/trusty/Android.bp
new file mode 100644
index 0000000..38c6204
--- /dev/null
+++ b/trusty/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["system_core_trusty_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "system_core_trusty_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-MIT",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
diff --git a/trusty/OWNERS b/trusty/OWNERS
index 1fb473e..5c4e03a 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -1,7 +1,7 @@
-arve@google.com
-dkrahn@google.com
-drewry@google.com
+armellel@google.com
+arve@android.com
gmar@google.com
+marcone@google.com
mmaurer@google.com
ncbray@google.com
swillden@google.com
diff --git a/trusty/apploader/Android.bp b/trusty/apploader/Android.bp
index 7e97cb8..4411964 100644
--- a/trusty/apploader/Android.bp
+++ b/trusty/apploader/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "trusty_apploader",
vendor: true,
diff --git a/trusty/apploader/apploader.cpp b/trusty/apploader/apploader.cpp
index 5d5d882..8ab6303 100644
--- a/trusty/apploader/apploader.cpp
+++ b/trusty/apploader/apploader.cpp
@@ -43,7 +43,7 @@
static const char* dev_name = kTrustyDefaultDeviceName;
-static const char* _sopts = "hs";
+static const char* _sopts = "hD:";
static const struct option _lopts[] = {
{"help", no_argument, 0, 'h'},
{"dev", required_argument, 0, 'D'},
diff --git a/trusty/apploader/fuzz/Android.bp b/trusty/apploader/fuzz/Android.bp
new file mode 100644
index 0000000..e37dab1
--- /dev/null
+++ b/trusty/apploader/fuzz/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Fuzz Trusty IPC messages sent to apploader.
+cc_fuzz {
+ name: "trusty_apploader_tipc_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.apploader\"",
+ "-DTRUSTY_APP_UUID=\"081ba88f-f1ee-452e-b5e8-a7e9ef173a97\"",
+ "-DTRUSTY_APP_FILENAME=\"apploader.syms.elf\"",
+ ]
+}
+
+// Fuzz app package sent to apploader.
+cc_fuzz {
+ name: "trusty_apploader_app_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: ["app_fuzzer.cpp"],
+ include_dirs: ["system/core/trusty/apploader"],
+ shared_libs: [
+ "libdmabufheap",
+ ],
+}
diff --git a/trusty/apploader/fuzz/app_fuzzer.cpp b/trusty/apploader/fuzz/app_fuzzer.cpp
new file mode 100644
index 0000000..aa0caca
--- /dev/null
+++ b/trusty/apploader/fuzz/app_fuzzer.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <BufferAllocator/BufferAllocator.h>
+#include <android-base/unique_fd.h>
+#include <apploader_ipc.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <trusty/tipc.h>
+#include <unistd.h>
+#include <iostream>
+
+using android::base::unique_fd;
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+#define APPLOADER_PORT "com.android.trusty.apploader"
+#define APPLOADER_MODULE_NAME "apploader.syms.elf"
+
+/* Apploader TA's UUID is 081ba88f-f1ee-452e-b5e8-a7e9ef173a97 */
+static struct uuid apploader_uuid = {
+ 0x081ba88f,
+ 0xf1ee,
+ 0x452e,
+ {0xb5, 0xe8, 0xa7, 0xe9, 0xef, 0x17, 0x3a, 0x97},
+};
+
+static inline uintptr_t RoundPageUp(uintptr_t val) {
+ return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+}
+
+static bool SendLoadMsg(int chan, int dma_buf, size_t dma_buf_size) {
+ apploader_header hdr = {
+ .cmd = APPLOADER_CMD_LOAD_APPLICATION,
+ };
+ apploader_load_app_req req = {
+ .package_size = static_cast<uint64_t>(dma_buf_size),
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &req,
+ .iov_len = sizeof(req),
+ },
+ };
+ trusty_shm shm = {
+ .fd = dma_buf,
+ .transfer = TRUSTY_SHARE,
+ };
+
+ int rc = tipc_send(chan, iov, 2, &shm, 1);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(req))) {
+ std::cerr << "Failed to send request" << std::endl;
+ return false;
+ }
+
+ apploader_resp resp;
+ rc = read(chan, &resp, sizeof(resp));
+ if (rc != static_cast<int>(sizeof(resp))) {
+ std::cerr << "Failed to receive response" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+static CoverageRecord record(TIPC_DEV, &apploader_uuid, APPLOADER_MODULE_NAME);
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+ auto ret = record.Open();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ExtraCounters counters(&record);
+ counters.Reset();
+
+ android::trusty::fuzz::TrustyApp ta(TIPC_DEV, APPLOADER_PORT);
+ auto ret = ta.Connect();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ android::trusty::fuzz::Abort();
+ }
+
+ uint64_t shm_len = size ? RoundPageUp(size) : PAGE_SIZE;
+ BufferAllocator alloc;
+ unique_fd dma_buf(alloc.Alloc(kDmabufSystemHeapName, shm_len));
+ if (dma_buf < 0) {
+ std::cerr << "Failed to create dmabuf of size: " << shm_len << std::endl;
+ android::trusty::fuzz::Abort();
+ }
+
+ void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+ if (shm_base == MAP_FAILED) {
+ std::cerr << "Failed to mmap() dmabuf" << std::endl;
+ android::trusty::fuzz::Abort();
+ }
+
+ memcpy(shm_base, data, size);
+
+ bool success = SendLoadMsg(*ta.GetRawFd(), dma_buf, shm_len);
+ if (!success) {
+ std::cerr << "Failed to send load message" << std::endl;
+ android::trusty::fuzz::Abort();
+ }
+
+ munmap(shm_base, shm_len);
+ return 0;
+}
diff --git a/trusty/confirmationui/Android.bp b/trusty/confirmationui/Android.bp
index 60e0e71..0922415 100644
--- a/trusty/confirmationui/Android.bp
+++ b/trusty/confirmationui/Android.bp
@@ -19,6 +19,10 @@
// to only building on ARM if they include assembly. Individual makefiles
// are responsible for having their own logic, for fine-grained control.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "android.hardware.confirmationui@1.0-service.trusty",
relative_install_path: "hw",
@@ -54,6 +58,7 @@
"android.hardware.confirmationui@1.0",
"android.hardware.keymaster@4.0",
"libbase",
+ "libdmabufheap",
"libhidlbase",
"libteeui_hal_support",
"libtrusty",
@@ -92,4 +97,4 @@
"-Werror",
"-DTEEUI_USE_STD_VECTOR",
],
-}
\ No newline at end of file
+}
diff --git a/trusty/confirmationui/TrustyApp.cpp b/trusty/confirmationui/TrustyApp.cpp
index e4c68f9..cee8655 100644
--- a/trusty/confirmationui/TrustyApp.cpp
+++ b/trusty/confirmationui/TrustyApp.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2020, The Android Open Source Project
+ * Copyright 2021, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,141 +16,152 @@
#include "TrustyApp.h"
+#include <BufferAllocator/BufferAllocator.h>
#include <android-base/logging.h>
+#include <sys/mman.h>
#include <sys/uio.h>
#include <trusty/tipc.h>
+#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
+
namespace android {
namespace trusty {
+namespace confirmationui {
-// 0x1000 is the message buffer size but we need to leave some space for a protocol header.
-// This assures that packets can always be read/written in one read/write operation.
-static constexpr const uint32_t kPacketSize = 0x1000 - 32;
+using ::android::base::unique_fd;
-enum class PacketType : uint32_t {
- SND,
- RCV,
- ACK,
-};
-
-struct PacketHeader {
- PacketType type;
- uint32_t remaining;
-};
-
-const char* toString(PacketType t) {
- switch (t) {
- case PacketType::SND:
- return "SND";
- case PacketType::RCV:
- return "RCV";
- case PacketType::ACK:
- return "ACK";
- default:
- return "UNKNOWN";
- }
+static inline uintptr_t RoundPageUp(uintptr_t val) {
+ return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
}
-static constexpr const uint32_t kHeaderSize = sizeof(PacketHeader);
-static constexpr const uint32_t kPayloadSize = kPacketSize - kHeaderSize;
+ssize_t TrustyApp::TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
+ uint8_t* iend) {
+ uint32_t olen = oend - obegin;
-ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
- uint8_t* iend) {
- while (obegin != oend) {
- PacketHeader header = {
- .type = PacketType::SND,
- .remaining = uint32_t(oend - obegin),
- };
- uint32_t body_size = std::min(kPayloadSize, header.remaining);
- iovec iov[] = {
- {
- .iov_base = &header,
- .iov_len = kHeaderSize,
- },
- {
- .iov_base = const_cast<uint8_t*>(obegin),
- .iov_len = body_size,
- },
- };
- int rc = writev(handle, iov, 2);
- if (!rc) {
- PLOG(ERROR) << "Error sending SND message. " << rc;
- return rc;
- }
-
- obegin += body_size;
-
- rc = read(handle, &header, kHeaderSize);
- if (!rc) {
- PLOG(ERROR) << "Error reading ACK. " << rc;
- return rc;
- }
-
- if (header.type != PacketType::ACK || header.remaining != oend - obegin) {
- LOG(ERROR) << "malformed ACK";
- return -1;
- }
+ if (olen > shm_len_) {
+ LOG(ERROR) << AT << "request message too long to fit in shared memory";
+ return -1;
}
- ssize_t remaining = 0;
- auto begin = ibegin;
- do {
- PacketHeader header = {
- .type = PacketType::RCV,
- .remaining = 0,
- };
+ memcpy(shm_base_, obegin, olen);
- iovec iov[] = {
- {
- .iov_base = &header,
- .iov_len = kHeaderSize,
- },
- {
- .iov_base = begin,
- .iov_len = uint32_t(iend - begin),
- },
- };
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_MSG,
+ };
+ confirmationui_msg_args args = {
+ .msg_len = olen,
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
- ssize_t rc = writev(handle, iov, 1);
- if (!rc) {
- PLOG(ERROR) << "Error sending RCV message. " << rc;
- return rc;
- }
+ int rc = tipc_send(handle_, iov, countof(iov), NULL, 0);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to send MSG request";
+ return -1;
+ }
- rc = readv(handle, iov, 2);
- if (rc < 0) {
- PLOG(ERROR) << "Error reading response. " << rc;
- return rc;
- }
+ rc = readv(handle_, iov, countof(iov));
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to receive MSG response";
+ return -1;
+ }
- uint32_t body_size = std::min(kPayloadSize, header.remaining);
- if (body_size != rc - kHeaderSize) {
- LOG(ERROR) << "Unexpected amount of data: " << rc;
- return -1;
- }
+ if (hdr.cmd != (CONFIRMATIONUI_CMD_MSG | CONFIRMATIONUI_RESP_BIT)) {
+ LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
+ return -1;
+ }
- remaining = header.remaining - body_size;
- begin += body_size;
- } while (remaining);
+ uint32_t ilen = iend - ibegin;
+ if (args.msg_len > ilen) {
+ LOG(ERROR) << AT << "response message too long to fit in return buffer";
+ return -1;
+ }
- return begin - ibegin;
+ memcpy(ibegin, shm_base_, args.msg_len);
+
+ return args.msg_len;
}
TrustyApp::TrustyApp(const std::string& path, const std::string& appname)
: handle_(kInvalidHandle) {
- handle_ = tipc_connect(path.c_str(), appname.c_str());
- if (handle_ == kInvalidHandle) {
+ unique_fd tipc_handle(tipc_connect(path.c_str(), appname.c_str()));
+ if (tipc_handle < 0) {
LOG(ERROR) << AT << "failed to connect to Trusty TA \"" << appname << "\" using dev:"
<< "\"" << path << "\"";
+ return;
}
+
+ uint32_t shm_len = RoundPageUp(CONFIRMATIONUI_MAX_MSG_SIZE);
+ BufferAllocator allocator;
+ unique_fd dma_buf(allocator.Alloc("system", shm_len));
+ if (dma_buf < 0) {
+ LOG(ERROR) << AT << "failed to allocate shared memory buffer";
+ return;
+ }
+
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_INIT,
+ };
+ confirmationui_init_req args = {
+ .shm_len = shm_len,
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
+ trusty_shm shm = {
+ .fd = dma_buf,
+ .transfer = TRUSTY_SHARE,
+ };
+
+ int rc = tipc_send(tipc_handle, iov, 2, &shm, 1);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to send INIT request";
+ return;
+ }
+
+ rc = read(tipc_handle, &hdr, sizeof(hdr));
+ if (rc != static_cast<int>(sizeof(hdr))) {
+ LOG(ERROR) << AT << "failed to receive INIT response";
+ return;
+ }
+
+ if (hdr.cmd != (CONFIRMATIONUI_CMD_INIT | CONFIRMATIONUI_RESP_BIT)) {
+ LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
+ return;
+ }
+
+ void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+ if (shm_base == MAP_FAILED) {
+ LOG(ERROR) << AT << "failed to mmap() shared memory buffer";
+ return;
+ }
+
+ handle_ = std::move(tipc_handle);
+ shm_base_ = shm_base;
+ shm_len_ = shm_len;
+
LOG(INFO) << AT << "succeeded to connect to Trusty TA \"" << appname << "\"";
}
+
TrustyApp::~TrustyApp() {
- if (handle_ != kInvalidHandle) {
- tipc_close(handle_);
- }
LOG(INFO) << "Done shutting down TrustyApp";
}
+} // namespace confirmationui
} // namespace trusty
} // namespace android
diff --git a/trusty/confirmationui/TrustyApp.h b/trusty/confirmationui/TrustyApp.h
index 05a25f6..fb57828 100644
--- a/trusty/confirmationui/TrustyApp.h
+++ b/trusty/confirmationui/TrustyApp.h
@@ -16,7 +16,10 @@
#pragma once
+#include <TrustyIpc.h>
+
#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
@@ -38,6 +41,7 @@
namespace android {
namespace trusty {
+namespace confirmationui {
using ::teeui::Message;
using ::teeui::msg2tuple_t;
@@ -60,19 +64,11 @@
MSG_TOO_LONG = -2,
};
-/*
- * There is a hard limitation of 0x1800 bytes for the to-be-signed message size. The protocol
- * overhead is limited, so that 0x2000 is a buffer size that will be sufficient in any benign
- * mode of operation.
- */
-static constexpr const size_t kSendBufferSize = 0x2000;
-
-ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
- uint8_t* iend);
-
class TrustyApp {
private:
- int handle_;
+ android::base::unique_fd handle_;
+ void* shm_base_;
+ size_t shm_len_;
static constexpr const int kInvalidHandle = -1;
/*
* This mutex serializes communication with the trusted app, not handle_.
@@ -84,6 +80,8 @@
TrustyApp(const std::string& path, const std::string& appname);
~TrustyApp();
+ ssize_t TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin, uint8_t* iend);
+
template <typename Request, typename Response, typename... T>
std::tuple<TrustyAppError, msg2tuple_t<Response>> issueCmd(const T&... args) {
std::lock_guard<std::mutex> lock(mutex_);
@@ -93,7 +91,7 @@
return {TrustyAppError::ERROR, {}};
}
- uint8_t buffer[kSendBufferSize];
+ uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
WriteStream out(buffer);
out = write(Request(), out, args...);
@@ -102,8 +100,8 @@
return {TrustyAppError::MSG_TOO_LONG, {}};
}
- auto rc = TrustyRpc(handle_, &buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
- &buffer[kSendBufferSize]);
+ auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
+ &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
if (rc < 0) return {TrustyAppError::ERROR, {}};
ReadStream in(&buffer[0], rc);
@@ -125,7 +123,7 @@
return TrustyAppError::ERROR;
}
- uint8_t buffer[kSendBufferSize];
+ uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
WriteStream out(buffer);
out = write(Request(), out, args...);
@@ -134,8 +132,8 @@
return TrustyAppError::MSG_TOO_LONG;
}
- auto rc = TrustyRpc(handle_, &buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
- &buffer[kSendBufferSize]);
+ auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
+ &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
if (rc < 0) {
LOG(ERROR) << "send command failed: " << strerror(errno) << " (" << errno << ")";
return TrustyAppError::ERROR;
@@ -151,5 +149,6 @@
operator bool() const { return handle_ != kInvalidHandle; }
};
+} // namespace confirmationui
} // namespace trusty
} // namespace android
diff --git a/trusty/confirmationui/TrustyConfirmationUI.cpp b/trusty/confirmationui/TrustyConfirmationUI.cpp
index 6b25893..c6625e0 100644
--- a/trusty/confirmationui/TrustyConfirmationUI.cpp
+++ b/trusty/confirmationui/TrustyConfirmationUI.cpp
@@ -50,7 +50,7 @@
using namespace secure_input;
-using ::android::trusty::TrustyAppError;
+using ::android::trusty::confirmationui::TrustyAppError;
using ::teeui::AbortMsg;
using ::teeui::DeliverTestCommandMessage;
@@ -71,7 +71,7 @@
using TeeuiRc = ::teeui::ResponseCode;
constexpr const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
-constexpr const char kConfirmationuiAppName[] = "com.android.trusty.confirmationui";
+constexpr const char kConfirmationuiAppName[] = CONFIRMATIONUI_PORT;
namespace {
diff --git a/trusty/confirmationui/TrustyConfirmationUI.h b/trusty/confirmationui/TrustyConfirmationUI.h
index 3a7c7ef..0bd703c 100644
--- a/trusty/confirmationui/TrustyConfirmationUI.h
+++ b/trusty/confirmationui/TrustyConfirmationUI.h
@@ -43,7 +43,7 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::trusty::TrustyApp;
+using ::android::trusty::confirmationui::TrustyApp;
class TrustyConfirmationUI : public IConfirmationUI {
public:
diff --git a/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc b/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
index dc7a03b..3ba6fc0 100644
--- a/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
+++ b/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
@@ -1,4 +1,4 @@
service confirmationui-1-0 /vendor/bin/hw/android.hardware.confirmationui@1.0-service.trusty
class hal
- user nobody
- group drmrpc input
+ user system
+ group drmrpc input system
diff --git a/trusty/confirmationui/fuzz/Android.bp b/trusty/confirmationui/fuzz/Android.bp
index 635966f..ba57191 100644
--- a/trusty/confirmationui/fuzz/Android.bp
+++ b/trusty/confirmationui/fuzz/Android.bp
@@ -12,12 +12,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_fuzz {
- name: "trusty_confirmationui_fuzzer",
- defaults: ["trusty_fuzzer_defaults"],
- srcs: ["fuzz.cpp"],
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
- // The initial corpus for this fuzzer was derived by dumping bytes from
- // ConfirmationUI VTS.
- corpus: ["corpus/*"],
+cc_fuzz {
+ name: "trusty_confirmationui_tipc_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.confirmationui\"",
+ "-DTRUSTY_APP_UUID=\"7dee2364-c036-425b-b086-df0f6c233c1b\"",
+ "-DTRUSTY_APP_FILENAME=\"confirmationui.syms.elf\"",
+ ],
+
+}
+
+cc_fuzz {
+ name: "trusty_confirmationui_msg_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: ["msg_fuzzer.cpp"],
+ include_dirs: ["system/core/trusty/confirmationui/include"],
+ shared_libs: [
+ "libdmabufheap",
+ ],
+
+ // The initial corpus for this fuzzer was derived by dumping messages from/to
+ // HAL to/from TA triggered by VtsHalConfirmationUIV1_0TargetTest.
+ corpus: ["msg_corpus/*"],
}
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2 b/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2
deleted file mode 100644
index 53fe0c9..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq b/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq
deleted file mode 100644
index bda80fd..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO b/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3 b/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO b/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR b/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR
deleted file mode 100644
index f5854f8..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi b/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j b/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs b/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T b/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T
deleted file mode 100644
index 0dc6e91..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO b/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO
deleted file mode 100644
index 927d64d..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B b/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-globJV b/trusty/confirmationui/fuzz/corpus/confirmationui-globJV
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-globJV
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD b/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o b/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o
deleted file mode 100644
index 0b274bf..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni b/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t b/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI b/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me b/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK b/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks b/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks
deleted file mode 100644
index b4a1c49..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN b/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/fuzz.cpp b/trusty/confirmationui/fuzz/fuzz.cpp
deleted file mode 100644
index df2517c..0000000
--- a/trusty/confirmationui/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-#include <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
-#define CONFIRMATIONUI_MODULE_NAME "confirmationui.syms.elf"
-
-/* ConfirmationUI TA's UUID is 7dee2364-c036-425b-b086-df0f6c233c1b */
-static struct uuid confirmationui_uuid = {
- 0x7dee2364,
- 0xc036,
- 0x425b,
- {0xb0, 0x86, 0xdf, 0x0f, 0x6c, 0x23, 0x3c, 0x1b},
-};
-
-/* The format of the packets is as following:
- * 16 bits (uint16_t, header) + payload bytes
- * The 16 bits header spicify the number of bytes of payload (header excluded).
- */
-struct data_packet {
- uint16_t header;
- uint8_t payload[];
-};
-
-static CoverageRecord record(TIPC_DEV, &confirmationui_uuid, CONFIRMATIONUI_MODULE_NAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
- auto ret = record.Open();
- if (!ret.ok()) {
- std::cerr << ret.error() << std::endl;
- exit(-1);
- }
- return 0;
-}
-
-/* Each corpus contains one or more data packets. */
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static uint8_t buf[TIPC_MAX_MSG_SIZE];
- size_t data_idx = 0;
-
- ExtraCounters counters(&record);
- counters.Reset();
-
- TrustyApp ta(TIPC_DEV, CONFIRMATIONUI_PORT);
- auto ret = ta.Connect();
- if (!ret.ok()) {
- android::trusty::fuzz::Abort();
- }
-
- while (data_idx < size) {
- struct data_packet* data_packet_ptr = (struct data_packet*)&data[data_idx];
- size_t payload_size = data_packet_ptr->header;
- data_idx += data_packet_ptr->header + sizeof(data_packet_ptr->header);
-
- /* Write message to confirmationui server */
- ret = ta.Write(data_packet_ptr->payload, payload_size);
- if (!ret.ok()) {
- return -1;
- }
-
- /* Read message from confirmationui server */
- ret = ta.Read(&buf, sizeof(buf));
- if (!ret.ok()) {
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl
new file mode 100644
index 0000000..c8741fb
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b
new file mode 100644
index 0000000..1682427
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi
new file mode 100644
index 0000000..d48e5a1
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq
new file mode 100644
index 0000000..6f72ad5
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP
new file mode 100644
index 0000000..8be96c5
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
similarity index 95%
rename from trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f
rename to trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
index d627b01..b944d94 100644
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX
new file mode 100644
index 0000000..1d9374d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz
new file mode 100644
index 0000000..b3be8cd
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS
new file mode 100644
index 0000000..1d9374d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30
new file mode 100644
index 0000000..38e3fca
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs
new file mode 100644
index 0000000..cbfd07a
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp
new file mode 100644
index 0000000..ecaec12
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE
new file mode 100644
index 0000000..58b1526
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r
new file mode 100644
index 0000000..af570ea
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs
new file mode 100644
index 0000000..e4b99fb
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang
new file mode 100644
index 0000000..d114956
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb
new file mode 100644
index 0000000..6caf7dd
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14
new file mode 100644
index 0000000..ecaec12
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw
new file mode 100644
index 0000000..36445d9
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC
new file mode 100644
index 0000000..f6c6dcf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH
new file mode 100644
index 0000000..d6ba1fc
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_fuzzer.cpp b/trusty/confirmationui/fuzz/msg_fuzzer.cpp
new file mode 100644
index 0000000..8e4443c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_fuzzer.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <BufferAllocator/BufferAllocator.h>
+#include <TrustyIpc.h>
+#include <iostream>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <trusty/tipc.h>
+#include <unistd.h>
+
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
+#define CONFIRMATIONUI_MODULE_NAME "confirmationui.syms.elf"
+
+/* A request to render to screen may take a while. */
+const size_t kTimeoutSeconds = 30;
+
+/* ConfirmationUI TA's UUID is 7dee2364-c036-425b-b086-df0f6c233c1b */
+static struct uuid confirmationui_uuid = {
+ 0x7dee2364,
+ 0xc036,
+ 0x425b,
+ {0xb0, 0x86, 0xdf, 0x0f, 0x6c, 0x23, 0x3c, 0x1b},
+};
+
+static CoverageRecord record(TIPC_DEV, &confirmationui_uuid, CONFIRMATIONUI_MODULE_NAME);
+
+static android::base::unique_fd dma_buf;
+static void* shm_base;
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+ auto ret = record.Open();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
+
+ BufferAllocator allocator;
+ dma_buf.reset(allocator.Alloc(kDmabufSystemHeapName, CONFIRMATIONUI_MAX_MSG_SIZE));
+ if (dma_buf < 0) {
+ std::cerr << "Failed to allocate dma_buf" << std::endl;
+ exit(-1);
+ }
+
+ shm_base = mmap(0, CONFIRMATIONUI_MAX_MSG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+ if (shm_base == MAP_FAILED) {
+ std::cerr << "Failed to mmap() dma_buf" << std::endl;
+ exit(-1);
+ }
+
+ return 0;
+}
+
+static bool Init(int chan, int dma_buf) {
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_INIT,
+ };
+ confirmationui_init_req args = {
+ .shm_len = CONFIRMATIONUI_MAX_MSG_SIZE,
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
+ trusty_shm shm = {
+ .fd = dma_buf,
+ .transfer = TRUSTY_SHARE,
+ };
+
+ int rc = tipc_send(chan, iov, countof(iov), &shm, 1);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ return false;
+ }
+
+ rc = read(chan, &hdr, sizeof(hdr));
+ if (rc != static_cast<int>(sizeof(hdr))) {
+ return false;
+ }
+
+ return true;
+}
+
+static bool Msg(int chan, const uint8_t* data, size_t size) {
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_MSG,
+ };
+ confirmationui_msg_args args = {
+ .msg_len = static_cast<uint32_t>(size),
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
+
+ memset(shm_base, 0, CONFIRMATIONUI_MAX_MSG_SIZE);
+ memcpy(shm_base, data, size);
+
+ int rc = tipc_send(chan, iov, countof(iov), NULL, 0);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ return false;
+ }
+
+ rc = readv(chan, iov, countof(iov));
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ExtraCounters counters(&record);
+ counters.Reset();
+
+ TrustyApp ta(TIPC_DEV, CONFIRMATIONUI_PORT);
+ auto ret = ta.Connect();
+ if (!ret.ok()) {
+ android::trusty::fuzz::Abort();
+ }
+ int chan = *ta.GetRawFd();
+
+ alarm(kTimeoutSeconds);
+ bool success = Init(chan, dma_buf);
+ alarm(0);
+ if (!success) {
+ android::trusty::fuzz::Abort();
+ }
+
+ alarm(kTimeoutSeconds);
+ success = Msg(chan, data, size);
+ alarm(0);
+ if (!success) {
+ android::trusty::fuzz::Abort();
+ }
+
+ return 0;
+}
diff --git a/trusty/confirmationui/include/TrustyIpc.h b/trusty/confirmationui/include/TrustyIpc.h
new file mode 100644
index 0000000..eb764bc
--- /dev/null
+++ b/trusty/confirmationui/include/TrustyIpc.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*
+ * This interface is shared between Android and Trusty. There is a copy in each
+ * repository. They must be kept in sync.
+ */
+
+#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
+
+/**
+ * enum confirmationui_cmd - command identifiers for ConfirmationUI interface
+ * @CONFIRMATIONUI_RESP_BIT: response bit set as part of response
+ * @CONFIRMATIONUI_REQ_SHIFT: number of bits used by response bit
+ * @CONFIRMATIONUI_CMD_INIT: command to initialize session
+ * @CONFIRMATIONUI_CMD_MSG: command to send ConfirmationUI messages
+ */
+enum confirmationui_cmd : uint32_t {
+ CONFIRMATIONUI_RESP_BIT = 1,
+ CONFIRMATIONUI_REQ_SHIFT = 1,
+
+ CONFIRMATIONUI_CMD_INIT = (1 << CONFIRMATIONUI_REQ_SHIFT),
+ CONFIRMATIONUI_CMD_MSG = (2 << CONFIRMATIONUI_REQ_SHIFT),
+};
+
+/**
+ * struct confirmationui_hdr - header for ConfirmationUI messages
+ * @cmd: command identifier
+ *
+ * Note that no messages return a status code. Any error on the server side
+ * results in the connection being closed. So, operations can be assumed to be
+ * successful if they return a response.
+ */
+struct confirmationui_hdr {
+ uint32_t cmd;
+};
+
+/**
+ * struct confirmationui_init_req - arguments for request to initialize a
+ * session
+ * @shm_len: length of memory region being shared
+ *
+ * A handle to a memory region must be sent along with this message. This memory
+ * is send to ConfirmationUI messages.
+ */
+struct confirmationui_init_req {
+ uint32_t shm_len;
+};
+
+/**
+ * struct confirmationui_msg_args - arguments for sending a message
+ * @msg_len: length of message being sent
+ *
+ * Contents of the message are located in the shared memory region that is
+ * established using %CONFIRMATIONUI_CMD_INIT.
+ *
+ * ConfirmationUI messages can travel both ways.
+ */
+struct confirmationui_msg_args {
+ uint32_t msg_len;
+};
+
+#define CONFIRMATIONUI_MAX_MSG_SIZE 0x2000
diff --git a/trusty/coverage/Android.bp b/trusty/coverage/Android.bp
index daa6f03..0453f3f 100644
--- a/trusty/coverage/Android.bp
+++ b/trusty/coverage/Android.bp
@@ -12,23 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library {
name: "libtrusty_coverage",
vendor_available: true,
srcs: [
"coverage.cpp",
+ "uuid.cpp",
],
export_include_dirs: [
"include",
],
- static_libs: [
- "libtrusty",
- ],
-
shared_libs: [
"libbase",
+ "libext2_uuid",
"liblog",
"libdmabufheap",
+ "libtrusty",
],
}
diff --git a/trusty/coverage/coverage.cpp b/trusty/coverage/coverage.cpp
index 5eccdc5..3c6b5c5 100644
--- a/trusty/coverage/coverage.cpp
+++ b/trusty/coverage/coverage.cpp
@@ -29,6 +29,7 @@
#include <trusty/coverage/record.h>
#include <trusty/coverage/tipc.h>
#include <trusty/tipc.h>
+#include <iostream>
#define COVERAGE_CLIENT_PORT "com.android.trusty.coverage.client"
@@ -122,7 +123,9 @@
int fd = tipc_connect(tipc_dev_.c_str(), COVERAGE_CLIENT_PORT);
if (fd < 0) {
- return ErrnoError() << "failed to connect to Trusty coverarge server: ";
+ // Don't error out to support fuzzing builds without coverage, e.g. for repros.
+ std::cerr << "WARNING!!! Failed to connect to Trusty coverarge server." << std::endl;
+ return {};
}
coverage_srv_fd_.reset(fd);
@@ -130,7 +133,7 @@
req.open_args.uuid = uuid_;
auto ret = Rpc(&req, -1, &resp);
if (!ret.ok()) {
- return Error() << "failed to open coverage client: ";
+ return Error() << "failed to open coverage client: " << ret.error();
}
record_len_ = resp.open_args.record_len;
shm_len_ = RoundPageUp(record_len_);
@@ -153,13 +156,17 @@
req.share_record_args.shm_len = shm_len_;
ret = Rpc(&req, dma_buf, &resp);
if (!ret.ok()) {
- return Error() << "failed to send shared memory: ";
+ return Error() << "failed to send shared memory: " << ret.error();
}
shm_ = shm;
return {};
}
+bool CoverageRecord::IsOpen() {
+ return shm_;
+}
+
void CoverageRecord::ResetFullRecord() {
auto header_region = GetRegionBounds(COV_START);
if (!header_region.ok()) {
diff --git a/trusty/coverage/include/trusty/coverage/coverage.h b/trusty/coverage/include/trusty/coverage/coverage.h
index 5da68da..9ccc981 100644
--- a/trusty/coverage/include/trusty/coverage/coverage.h
+++ b/trusty/coverage/include/trusty/coverage/coverage.h
@@ -47,6 +47,7 @@
~CoverageRecord();
Result<void> Open();
+ bool IsOpen();
void ResetFullRecord();
void ResetCounts();
void ResetPCs();
diff --git a/trusty/coverage/include/trusty/coverage/tipc.h b/trusty/coverage/include/trusty/coverage/tipc.h
index c4157c4..386b2bb 100644
--- a/trusty/coverage/include/trusty/coverage/tipc.h
+++ b/trusty/coverage/include/trusty/coverage/tipc.h
@@ -19,16 +19,10 @@
#pragma once
#include <stdint.h>
+#include <trusty/coverage/uuid.h>
#define COVERAGE_CLIENT_PORT "com.android.trusty.coverage.client"
-struct uuid {
- uint32_t time_low;
- uint16_t time_mid;
- uint16_t time_hi_and_version;
- uint8_t clock_seq_and_node[8];
-};
-
enum coverage_client_cmd {
COVERAGE_CLIENT_CMD_RESP_BIT = 1U,
COVERAGE_CLIENT_CMD_SHIFT = 1U,
diff --git a/trusty/coverage/include/trusty/coverage/uuid.h b/trusty/coverage/include/trusty/coverage/uuid.h
new file mode 100644
index 0000000..c77d275
--- /dev/null
+++ b/trusty/coverage/include/trusty/coverage/uuid.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+struct uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_and_node[8];
+};
+
+/**
+ * str_to_uuid() - Converts a C string into a uuid
+ * @str: C-string representation of the uuid
+ * @uuid: &struct uuid to fill with the converted uuid
+ *
+ * Return: true on success, false otherwise
+ */
+bool str_to_uuid(const char* str, struct uuid* uuid);
diff --git a/trusty/coverage/uuid.cpp b/trusty/coverage/uuid.cpp
new file mode 100644
index 0000000..f0a6c0e
--- /dev/null
+++ b/trusty/coverage/uuid.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Sourete Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <trusty/coverage/uuid.h>
+#include <uuid.h>
+
+#include <stdio.h>
+
+static uint16_t reverse_u16(uint16_t u) {
+ return u << 8 | u >> 8;
+}
+
+static uint32_t reverse_u32(uint32_t u) {
+ return reverse_u16((uint16_t)u) << 16 | reverse_u16(u >> 16);
+}
+
+bool str_to_uuid(const char* str, struct uuid* uuid) {
+ uuid_t uu;
+ static_assert(sizeof(uu) == sizeof(*uuid));
+
+ if (uuid_parse(str, uu)) {
+ return false;
+ }
+
+ memcpy(uuid, uu, sizeof(*uuid));
+ uuid->time_low = reverse_u32(uuid->time_low);
+ uuid->time_mid = reverse_u16(uuid->time_mid);
+ uuid->time_hi_and_version = reverse_u16(uuid->time_hi_and_version);
+ return true;
+}
diff --git a/trusty/fuzz/Android.bp b/trusty/fuzz/Android.bp
index ad13816..d147767 100644
--- a/trusty/fuzz/Android.bp
+++ b/trusty/fuzz/Android.bp
@@ -12,9 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "trusty_fuzzer_defaults",
shared_libs: [
+ "libtrusty",
"libtrusty_coverage",
"libtrusty_fuzz_utils",
"libbase",
@@ -39,11 +44,20 @@
export_include_dirs: ["include"],
static_libs: [
"libFuzzer",
- "libtrusty",
],
shared_libs: [
"libtrusty_coverage",
"libbase",
"liblog",
+ "libtrusty",
],
}
+
+// Generic TIPC fuzzer, must parameterized using:
+// -DTRUSTY_APP_PORT=<port name of TA being fuzzed>
+// -DTRUSTY_APP_UUID=<UUID of TA being fuzzed>
+// -DTRUSTY_APP_FILENAME=<name of symbolized elf binary of the TA>
+filegroup {
+ name: "trusty_tipc_fuzzer",
+ srcs: ["tipc_fuzzer.cpp"],
+}
diff --git a/trusty/fuzz/counters.cpp b/trusty/fuzz/counters.cpp
index 1e863ac..c28fd05 100644
--- a/trusty/fuzz/counters.cpp
+++ b/trusty/fuzz/counters.cpp
@@ -33,7 +33,7 @@
* We don't know how many counters the coverage record will contain. So, eyeball
* the size of this section.
*/
-static const size_t kMaxNumCounters = 0x4000;
+static const size_t kMaxNumCounters = 0x8000;
__attribute__((section("__libfuzzer_extra_counters"))) volatile uint8_t counters[kMaxNumCounters];
namespace android {
@@ -41,6 +41,10 @@
namespace fuzz {
ExtraCounters::ExtraCounters(coverage::CoverageRecord* record) : record_(record) {
+ if (!record_->IsOpen()) {
+ return;
+ }
+
assert(fuzzer::ExtraCountersBegin());
assert(fuzzer::ExtraCountersEnd());
@@ -51,10 +55,18 @@
}
ExtraCounters::~ExtraCounters() {
+ if (!record_->IsOpen()) {
+ return;
+ }
+
Flush();
}
void ExtraCounters::Reset() {
+ if (!record_->IsOpen()) {
+ return;
+ }
+
record_->ResetCounts();
fuzzer::ClearExtraCounters();
}
diff --git a/trusty/fuzz/test/Android.bp b/trusty/fuzz/test/Android.bp
index 66e103d..7d74913 100644
--- a/trusty/fuzz/test/Android.bp
+++ b/trusty/fuzz/test/Android.bp
@@ -12,8 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_fuzz {
name: "trusty_test_fuzzer",
defaults: ["trusty_fuzzer_defaults"],
- srcs: ["fuzz.cpp"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.sancov.test.srv\"",
+ "-DTRUSTY_APP_UUID=\"77f68803-c514-43ba-bdce-3254531c3d24\"",
+ "-DTRUSTY_APP_FILENAME=\"srv.syms.elf\"",
+ ]
}
diff --git a/trusty/fuzz/test/fuzz.cpp b/trusty/fuzz/test/fuzz.cpp
deleted file mode 100644
index e7913db..0000000
--- a/trusty/fuzz/test/fuzz.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define TEST_SRV_PORT "com.android.trusty.sancov.test.srv"
-
-/* Test server's UUID is 77f68803-c514-43ba-bdce-3254531c3d24 */
-static struct uuid test_srv_uuid = {
- 0x77f68803,
- 0xc514,
- 0x43ba,
- {0xbd, 0xce, 0x32, 0x54, 0x53, 0x1c, 0x3d, 0x24},
-};
-
-static CoverageRecord record(TIPC_DEV, &test_srv_uuid);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
- auto ret = record.Open();
- if (!ret.ok()) {
- std::cerr << ret.error() << std::endl;
- exit(-1);
- }
- return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
- ExtraCounters counters(&record);
- counters.Reset();
-
- TrustyApp ta(TIPC_DEV, TEST_SRV_PORT);
- auto ret = ta.Connect();
- if (!ret.ok()) {
- android::trusty::fuzz::Abort();
- }
-
- /* Send message to test server */
- ret = ta.Write(data, size);
- if (!ret.ok()) {
- return -1;
- }
-
- /* Read message from test server */
- ret = ta.Read(&buf, sizeof(buf));
- if (!ret.ok()) {
- return -1;
- }
-
- return 0;
-}
diff --git a/trusty/fuzz/tipc_fuzzer.cpp b/trusty/fuzz/tipc_fuzzer.cpp
new file mode 100644
index 0000000..24b0f98
--- /dev/null
+++ b/trusty/fuzz/tipc_fuzzer.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/coverage/uuid.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+
+#ifndef TRUSTY_APP_PORT
+#error "Port name must be parameterized using -DTRUSTY_APP_PORT."
+#endif
+
+#ifndef TRUSTY_APP_UUID
+#error "UUID must be parameterized using -DTRUSTY_APP_UUID."
+#endif
+
+#ifndef TRUSTY_APP_FILENAME
+#error "Binary file name must be parameterized using -DTRUSTY_APP_FILENAME."
+#endif
+
+static std::unique_ptr<CoverageRecord> record;
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+ uuid module_uuid;
+
+ if (!str_to_uuid(TRUSTY_APP_UUID, &module_uuid)) {
+ std::cerr << "Failed to parse UUID: " << TRUSTY_APP_UUID << std::endl;
+ exit(-1);
+ }
+
+ record = std::make_unique<CoverageRecord>(TIPC_DEV, &module_uuid, TRUSTY_APP_FILENAME);
+ if (!record) {
+ std::cerr << "Failed to allocate coverage record" << std::endl;
+ exit(-1);
+ }
+
+ auto ret = record->Open();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static uint8_t buf[TIPC_MAX_MSG_SIZE];
+
+ ExtraCounters counters(record.get());
+ counters.Reset();
+
+ TrustyApp ta(TIPC_DEV, TRUSTY_APP_PORT);
+ auto ret = ta.Connect();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ android::trusty::fuzz::Abort();
+ }
+
+ ret = ta.Write(data, size);
+ if (!ret.ok()) {
+ return -1;
+ }
+
+ ret = ta.Read(&buf, sizeof(buf));
+ if (!ret.ok()) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/trusty/fuzz/utils.cpp b/trusty/fuzz/utils.cpp
index f4cf0b6..3526337 100644
--- a/trusty/fuzz/utils.cpp
+++ b/trusty/fuzz/utils.cpp
@@ -113,7 +113,7 @@
int rc = write(ta_fd_, buf, len);
alarm(0);
if (rc < 0) {
- return Error() << "failed to read TIPC message from TA: ";
+ return Error() << "failed to write TIPC message to TA: ";
}
return {};
diff --git a/trusty/gatekeeper/Android.bp b/trusty/gatekeeper/Android.bp
index e553af1..81f012f 100644
--- a/trusty/gatekeeper/Android.bp
+++ b/trusty/gatekeeper/Android.bp
@@ -19,6 +19,10 @@
// to only building on ARM if they include assembly. Individual makefiles
// are responsible for having their own logic, for fine-grained control.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "android.hardware.gatekeeper@1.0-service.trusty",
defaults: ["hidl_defaults"],
diff --git a/trusty/gatekeeper/fuzz/Android.bp b/trusty/gatekeeper/fuzz/Android.bp
index 7ffa776..d084cb6 100644
--- a/trusty/gatekeeper/fuzz/Android.bp
+++ b/trusty/gatekeeper/fuzz/Android.bp
@@ -12,10 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_fuzz {
name: "trusty_gatekeeper_fuzzer",
defaults: ["trusty_fuzzer_defaults"],
- srcs: ["fuzz.cpp"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.gatekeeper\"",
+ "-DTRUSTY_APP_UUID=\"38ba0cdc-df0e-11e4-9869-233fb6ae4795\"",
+ "-DTRUSTY_APP_FILENAME=\"gatekeeper.syms.elf\"",
+ ],
// The initial corpus for this fuzzer was derived by dumping messages from
// the `secure_env` emulator interface for cuttlefish while enrolling a new
diff --git a/trusty/gatekeeper/fuzz/fuzz.cpp b/trusty/gatekeeper/fuzz/fuzz.cpp
deleted file mode 100644
index 7bfd7d1..0000000
--- a/trusty/gatekeeper/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define GATEKEEPER_PORT "com.android.trusty.gatekeeper"
-#define GATEKEEPER_MODULE_NAME "gatekeeper.syms.elf"
-
-/* Gatekeeper TA's UUID is 38ba0cdc-df0e-11e4-9869-233fb6ae4795 */
-static struct uuid gatekeeper_uuid = {
- 0x38ba0cdc,
- 0xdf0e,
- 0x11e4,
- {0x98, 0x69, 0x23, 0x3f, 0xb6, 0xae, 0x47, 0x95},
-};
-
-static CoverageRecord record(TIPC_DEV, &gatekeeper_uuid, GATEKEEPER_MODULE_NAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
- auto ret = record.Open();
- if (!ret.ok()) {
- std::cerr << ret.error() << std::endl;
- exit(-1);
- }
- return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
- ExtraCounters counters(&record);
- counters.Reset();
-
- android::trusty::fuzz::TrustyApp ta(TIPC_DEV, GATEKEEPER_PORT);
- auto ret = ta.Connect();
- if (!ret.ok()) {
- android::trusty::fuzz::Abort();
- }
-
- /* Send message to test server */
- ret = ta.Write(data, size);
- if (!ret.ok()) {
- return -1;
- }
-
- /* Read message from test server */
- ret = ta.Read(&buf, sizeof(buf));
- if (!ret.ok()) {
- return -1;
- }
-
- return 0;
-}
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 27e1a3f..6d24e84 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "android.hardware.keymaster@3.0-service.trusty",
defaults: ["hidl_defaults"],
@@ -107,4 +111,3 @@
"-Werror",
],
}
-
diff --git a/trusty/keymaster/fuzz/Android.bp b/trusty/keymaster/fuzz/Android.bp
index da9f9ec..8d7ee00 100644
--- a/trusty/keymaster/fuzz/Android.bp
+++ b/trusty/keymaster/fuzz/Android.bp
@@ -12,8 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_fuzz {
name: "trusty_keymaster_fuzzer",
defaults: ["trusty_fuzzer_defaults"],
- srcs: ["fuzz.cpp"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.keymaster\"",
+ "-DTRUSTY_APP_UUID=\"5f902ace-5e5c-4cd8-ae54-87b88c22ddaf\"",
+ "-DTRUSTY_APP_FILENAME=\"keymaster.syms.elf\"",
+ ],
+
+ // The initial corpus for this fuzzer was derived by dumping messages from
+ // the `secure_env` emulator interface for cuttlefish while running the
+ // keystore2 tests in the emulator.
+ corpus: ["corpus/*"],
}
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-1x0hJ5 b/trusty/keymaster/fuzz/corpus/keymaster-recv-1x0hJ5
new file mode 100644
index 0000000..4a292c1
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-1x0hJ5
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-5GV6mx b/trusty/keymaster/fuzz/corpus/keymaster-recv-5GV6mx
new file mode 100644
index 0000000..60301f6
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-5GV6mx
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-7RVbJ8 b/trusty/keymaster/fuzz/corpus/keymaster-recv-7RVbJ8
new file mode 100644
index 0000000..9ed8279
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-7RVbJ8
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-9ElJHi b/trusty/keymaster/fuzz/corpus/keymaster-recv-9ElJHi
new file mode 100644
index 0000000..69caf33
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-9ElJHi
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-9czLCR b/trusty/keymaster/fuzz/corpus/keymaster-recv-9czLCR
new file mode 100644
index 0000000..e9d7daf
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-9czLCR
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-BFx3FN b/trusty/keymaster/fuzz/corpus/keymaster-recv-BFx3FN
new file mode 100644
index 0000000..3ce16c3
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-BFx3FN
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-BXWpRA b/trusty/keymaster/fuzz/corpus/keymaster-recv-BXWpRA
new file mode 100644
index 0000000..c290b52
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-BXWpRA
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-DanwgH b/trusty/keymaster/fuzz/corpus/keymaster-recv-DanwgH
new file mode 100644
index 0000000..b1fb022
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-DanwgH
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-JP2pXq b/trusty/keymaster/fuzz/corpus/keymaster-recv-JP2pXq
new file mode 100644
index 0000000..2f9abcf
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-JP2pXq
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-T0YO5T b/trusty/keymaster/fuzz/corpus/keymaster-recv-T0YO5T
new file mode 100644
index 0000000..9ed8279
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-T0YO5T
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-TM26dO b/trusty/keymaster/fuzz/corpus/keymaster-recv-TM26dO
new file mode 100644
index 0000000..ec374e3
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-TM26dO
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-XcPQ60 b/trusty/keymaster/fuzz/corpus/keymaster-recv-XcPQ60
new file mode 100644
index 0000000..3ce16c3
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-XcPQ60
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-ZU4x5D b/trusty/keymaster/fuzz/corpus/keymaster-recv-ZU4x5D
new file mode 100644
index 0000000..1641d95
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-ZU4x5D
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-Zbzv1t b/trusty/keymaster/fuzz/corpus/keymaster-recv-Zbzv1t
new file mode 100644
index 0000000..96b965e
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-Zbzv1t
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-ZvweQK b/trusty/keymaster/fuzz/corpus/keymaster-recv-ZvweQK
new file mode 100644
index 0000000..e3a04ae
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-ZvweQK
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-d3OcR1 b/trusty/keymaster/fuzz/corpus/keymaster-recv-d3OcR1
new file mode 100644
index 0000000..920c5ed
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-d3OcR1
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-dc6Hmg b/trusty/keymaster/fuzz/corpus/keymaster-recv-dc6Hmg
new file mode 100644
index 0000000..49453d4
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-dc6Hmg
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-fn8Ksu b/trusty/keymaster/fuzz/corpus/keymaster-recv-fn8Ksu
new file mode 100644
index 0000000..b0408c6
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-fn8Ksu
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-ldnX1U b/trusty/keymaster/fuzz/corpus/keymaster-recv-ldnX1U
new file mode 100644
index 0000000..8d77e0e
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-ldnX1U
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-pqvh4n b/trusty/keymaster/fuzz/corpus/keymaster-recv-pqvh4n
new file mode 100644
index 0000000..8ac5b90
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-pqvh4n
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-pvwjne b/trusty/keymaster/fuzz/corpus/keymaster-recv-pvwjne
new file mode 100644
index 0000000..22d5232
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-pvwjne
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-pzxe39 b/trusty/keymaster/fuzz/corpus/keymaster-recv-pzxe39
new file mode 100644
index 0000000..8e955c1
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-pzxe39
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-tpykrY b/trusty/keymaster/fuzz/corpus/keymaster-recv-tpykrY
new file mode 100644
index 0000000..16d2121
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-tpykrY
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-tq6MsH b/trusty/keymaster/fuzz/corpus/keymaster-recv-tq6MsH
new file mode 100644
index 0000000..d5d7f02
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-tq6MsH
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-recv-zt2UIA b/trusty/keymaster/fuzz/corpus/keymaster-recv-zt2UIA
new file mode 100644
index 0000000..23c3ce8
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-recv-zt2UIA
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-3aKtgr b/trusty/keymaster/fuzz/corpus/keymaster-send-3aKtgr
new file mode 100644
index 0000000..bfee18a
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-3aKtgr
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-5Ays9I b/trusty/keymaster/fuzz/corpus/keymaster-send-5Ays9I
new file mode 100644
index 0000000..3e446c5
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-5Ays9I
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-7X098Z b/trusty/keymaster/fuzz/corpus/keymaster-send-7X098Z
new file mode 100644
index 0000000..5b1c30b
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-7X098Z
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-B6LYU4 b/trusty/keymaster/fuzz/corpus/keymaster-send-B6LYU4
new file mode 100644
index 0000000..e841836
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-B6LYU4
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-BZU7LF b/trusty/keymaster/fuzz/corpus/keymaster-send-BZU7LF
new file mode 100644
index 0000000..72ba6c4
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-BZU7LF
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-FxXsxg b/trusty/keymaster/fuzz/corpus/keymaster-send-FxXsxg
new file mode 100644
index 0000000..5dfd4f8
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-FxXsxg
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-NlxYoC b/trusty/keymaster/fuzz/corpus/keymaster-send-NlxYoC
new file mode 100644
index 0000000..992e3f5
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-NlxYoC
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-PzXetK b/trusty/keymaster/fuzz/corpus/keymaster-send-PzXetK
new file mode 100644
index 0000000..18506f2
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-PzXetK
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-RFmR3D b/trusty/keymaster/fuzz/corpus/keymaster-send-RFmR3D
new file mode 100644
index 0000000..6845257
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-RFmR3D
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-Tp6AJW b/trusty/keymaster/fuzz/corpus/keymaster-send-Tp6AJW
new file mode 100644
index 0000000..90df6da
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-Tp6AJW
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-V0leT7 b/trusty/keymaster/fuzz/corpus/keymaster-send-V0leT7
new file mode 100644
index 0000000..79512e4
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-V0leT7
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-X4Plz3 b/trusty/keymaster/fuzz/corpus/keymaster-send-X4Plz3
new file mode 100644
index 0000000..1423e64
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-X4Plz3
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-Xd5KiX b/trusty/keymaster/fuzz/corpus/keymaster-send-Xd5KiX
new file mode 100644
index 0000000..18506f2
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-Xd5KiX
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-Ztr5Rk b/trusty/keymaster/fuzz/corpus/keymaster-send-Ztr5Rk
new file mode 100644
index 0000000..9af5af3
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-Ztr5Rk
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-f6d6wM b/trusty/keymaster/fuzz/corpus/keymaster-send-f6d6wM
new file mode 100644
index 0000000..e8f79be
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-f6d6wM
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-jbzgHv b/trusty/keymaster/fuzz/corpus/keymaster-send-jbzgHv
new file mode 100644
index 0000000..3ee5434
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-jbzgHv
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-jiL5yp b/trusty/keymaster/fuzz/corpus/keymaster-send-jiL5yp
new file mode 100644
index 0000000..90beb99
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-jiL5yp
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-l5kqxc b/trusty/keymaster/fuzz/corpus/keymaster-send-l5kqxc
new file mode 100644
index 0000000..b2f606d
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-l5kqxc
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-l6zX2y b/trusty/keymaster/fuzz/corpus/keymaster-send-l6zX2y
new file mode 100644
index 0000000..77705e7
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-l6zX2y
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-ltPKls b/trusty/keymaster/fuzz/corpus/keymaster-send-ltPKls
new file mode 100644
index 0000000..fb637aa
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-ltPKls
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-n7sdVP b/trusty/keymaster/fuzz/corpus/keymaster-send-n7sdVP
new file mode 100644
index 0000000..054a7ed
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-n7sdVP
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-pKSjkT b/trusty/keymaster/fuzz/corpus/keymaster-send-pKSjkT
new file mode 100644
index 0000000..3ed7246
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-pKSjkT
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-rhVedc b/trusty/keymaster/fuzz/corpus/keymaster-send-rhVedc
new file mode 100644
index 0000000..bd545f1
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-rhVedc
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-tZJ2Ex b/trusty/keymaster/fuzz/corpus/keymaster-send-tZJ2Ex
new file mode 100644
index 0000000..72ee499
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-tZJ2Ex
Binary files differ
diff --git a/trusty/keymaster/fuzz/corpus/keymaster-send-tZlTSQ b/trusty/keymaster/fuzz/corpus/keymaster-send-tZlTSQ
new file mode 100644
index 0000000..e841836
--- /dev/null
+++ b/trusty/keymaster/fuzz/corpus/keymaster-send-tZlTSQ
Binary files differ
diff --git a/trusty/keymaster/fuzz/fuzz.cpp b/trusty/keymaster/fuzz/fuzz.cpp
deleted file mode 100644
index 4ac97bb..0000000
--- a/trusty/keymaster/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define KEYMASTER_PORT "com.android.trusty.keymaster"
-#define KEYMASTER_MODULE_FILENAME "keymaster.syms.elf"
-
-/* Keymaster TA's UUID is 5f902ace-5e5c-4cd8-ae54-87b88c22ddaf */
-static struct uuid keymaster_uuid = {
- 0x5f902ace,
- 0x5e5c,
- 0x4cd8,
- {0xae, 0x54, 0x87, 0xb8, 0x8c, 0x22, 0xdd, 0xaf},
-};
-
-static CoverageRecord record(TIPC_DEV, &keymaster_uuid, KEYMASTER_MODULE_FILENAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
- auto ret = record.Open();
- if (!ret.ok()) {
- std::cerr << ret.error() << std::endl;
- exit(-1);
- }
- return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
- ExtraCounters counters(&record);
- counters.Reset();
-
- android::trusty::fuzz::TrustyApp ta(TIPC_DEV, KEYMASTER_PORT);
- auto ret = ta.Connect();
- if (!ret.ok()) {
- android::trusty::fuzz::Abort();
- }
-
- /* Send message to test server */
- ret = ta.Write(data, size);
- if (!ret.ok()) {
- return -1;
- }
-
- /* Read message from test server */
- ret = ta.Read(&buf, sizeof(buf));
- if (!ret.ok()) {
- return -1;
- }
-
- return 0;
-}
diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp
index e0161a5..086051d 100644
--- a/trusty/libtrusty/Android.bp
+++ b/trusty/libtrusty/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "libtrusty_defaults",
srcs: ["trusty.c"],
diff --git a/trusty/libtrusty/tipc-test/Android.bp b/trusty/libtrusty/tipc-test/Android.bp
index 5e60d28..c7a8ae1 100644
--- a/trusty/libtrusty/tipc-test/Android.bp
+++ b/trusty/libtrusty/tipc-test/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "tipc-test",
vendor: true,
diff --git a/trusty/secure_dpu/Android.bp b/trusty/secure_dpu/Android.bp
index 0d57cea..39dd0b9 100644
--- a/trusty/secure_dpu/Android.bp
+++ b/trusty/secure_dpu/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "secure_dpu_headers",
vendor: true,
diff --git a/trusty/storage/interface/Android.bp b/trusty/storage/interface/Android.bp
index 18b4a5f..d031b0c 100644
--- a/trusty/storage/interface/Android.bp
+++ b/trusty/storage/interface/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libtrustystorageinterface",
vendor: true,
diff --git a/trusty/storage/lib/Android.bp b/trusty/storage/lib/Android.bp
index 2fba17e..f28308b 100644
--- a/trusty/storage/lib/Android.bp
+++ b/trusty/storage/lib/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libtrustystorage",
vendor: true,
diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp
index b93facb..a471435 100644
--- a/trusty/storage/proxy/Android.bp
+++ b/trusty/storage/proxy/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "storageproxyd",
vendor: true,
diff --git a/trusty/storage/tests/Android.bp b/trusty/storage/tests/Android.bp
index 536c3ca..891f543 100644
--- a/trusty/storage/tests/Android.bp
+++ b/trusty/storage/tests/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "secure-storage-unit-test",
vendor: true,
diff --git a/trusty/utils/rpmb_dev/Android.bp b/trusty/utils/rpmb_dev/Android.bp
index e923e82..c5853ef 100644
--- a/trusty/utils/rpmb_dev/Android.bp
+++ b/trusty/utils/rpmb_dev/Android.bp
@@ -11,6 +11,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_core_trusty_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["system_core_trusty_license"],
+}
+
cc_binary {
name: "rpmb_dev",
vendor: true,
diff --git a/trusty/utils/spiproxyd/Android.bp b/trusty/utils/spiproxyd/Android.bp
index c1d0987..81f3e73 100644
--- a/trusty/utils/spiproxyd/Android.bp
+++ b/trusty/utils/spiproxyd/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "spiproxyd",
vendor: true,
diff --git a/trusty/utils/trusty-ut-ctrl/Android.bp b/trusty/utils/trusty-ut-ctrl/Android.bp
index 664696a..6fc2a48 100644
--- a/trusty/utils/trusty-ut-ctrl/Android.bp
+++ b/trusty/utils/trusty-ut-ctrl/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "trusty-ut-ctrl",
vendor: true,
diff --git a/usbd/Android.bp b/usbd/Android.bp
index 6a339a1..22d171d 100644
--- a/usbd/Android.bp
+++ b/usbd/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "usbd",
init_rc: ["usbd.rc"],
diff --git a/watchdogd/Android.bp b/watchdogd/Android.bp
index 0fbc33c..0388208 100644
--- a/watchdogd/Android.bp
+++ b/watchdogd/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "watchdogd",
recovery_available: true,