Merge "Turn on LTO optmisations for libbinder" into main
diff --git a/cmds/dumpstate/DumpstateUtil.cpp b/cmds/dumpstate/DumpstateUtil.cpp
index 615701c..4842312 100644
--- a/cmds/dumpstate/DumpstateUtil.cpp
+++ b/cmds/dumpstate/DumpstateUtil.cpp
@@ -207,7 +207,9 @@
int PropertiesHelper::dry_run_ = -1;
int PropertiesHelper::unroot_ = -1;
int PropertiesHelper::parallel_run_ = -1;
+#if !defined(__ANDROID_VNDK__)
int PropertiesHelper::strict_run_ = -1;
+#endif
bool PropertiesHelper::IsUserBuild() {
if (build_type_.empty()) {
@@ -238,6 +240,7 @@
return parallel_run_ == 1;
}
+#if !defined(__ANDROID_VNDK__)
bool PropertiesHelper::IsStrictRun() {
if (strict_run_ == -1) {
// Defaults to using stricter timeouts.
@@ -245,6 +248,7 @@
}
return strict_run_ == 1;
}
+#endif
int DumpFileToFd(int out_fd, const std::string& title, const std::string& path) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
diff --git a/cmds/dumpstate/DumpstateUtil.h b/cmds/dumpstate/DumpstateUtil.h
index 9e955e3..6049e3e 100644
--- a/cmds/dumpstate/DumpstateUtil.h
+++ b/cmds/dumpstate/DumpstateUtil.h
@@ -198,14 +198,18 @@
* will default to true. This results in shortened timeouts for flaky
* sections.
*/
+#if !defined(__ANDROID_VNDK__)
static bool IsStrictRun();
+#endif
private:
static std::string build_type_;
static int dry_run_;
static int unroot_;
static int parallel_run_;
+#if !defined(__ANDROID_VNDK__)
static int strict_run_;
+#endif
};
/*
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index 5cf402c..df02588 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -18,6 +18,7 @@
#define DEXOPT_H_
#include "installd_constants.h"
+#include "unique_file.h"
#include <sys/types.h>
@@ -156,6 +157,10 @@
// artifacts.
int get_odex_visibility(const char* apk_path, const char* instruction_set, const char* oat_dir);
+UniqueFile maybe_open_reference_profile(const std::string& pkgname, const std::string& dex_path,
+ const char* profile_name, bool profile_guided,
+ bool is_public, int uid, bool is_secondary_dex);
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 7cabdb0..818fd80 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -14,20 +14,21 @@
** limitations under the License.
*/
-#include <algorithm>
#include <inttypes.h>
-#include <limits>
-#include <random>
-#include <regex>
#include <selinux/android.h>
#include <selinux/avc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
+#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <sys/wait.h>
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#include <random>
+#include <regex>
#include <android-base/logging.h>
#include <android-base/macros.h>
@@ -47,6 +48,7 @@
#include "otapreopt_parameters.h"
#include "otapreopt_utils.h"
#include "system_properties.h"
+#include "unique_file.h"
#include "utils.h"
#ifndef LOG_TAG
@@ -87,6 +89,9 @@
static_assert(DEXOPT_MASK == (0x3dfe | DEXOPT_IDLE_BACKGROUND_JOB),
"DEXOPT_MASK unexpected.");
+constexpr const char* kAotCompilerFilters[]{
+ "space-profile", "space", "speed-profile", "speed", "everything-profile", "everything",
+};
template<typename T>
static constexpr bool IsPowerOfTwo(T x) {
@@ -415,6 +420,32 @@
return (strcmp(arg, "!") == 0) ? nullptr : arg;
}
+ bool IsAotCompilation() const {
+ if (std::find(std::begin(kAotCompilerFilters), std::end(kAotCompilerFilters),
+ parameters_.compiler_filter) == std::end(kAotCompilerFilters)) {
+ return false;
+ }
+
+ int dexopt_flags = parameters_.dexopt_flags;
+ bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
+ bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0;
+ bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
+
+ if (profile_guided) {
+ UniqueFile reference_profile =
+ maybe_open_reference_profile(parameters_.pkgName, parameters_.apk_path,
+ parameters_.profile_name, profile_guided,
+ is_public, parameters_.uid, is_secondary_dex);
+ struct stat sbuf;
+ if (reference_profile.fd() == -1 ||
+ (fstat(reference_profile.fd(), &sbuf) != -1 && sbuf.st_size == 0)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool ShouldSkipPreopt() const {
// There's one thing we have to be careful about: we may/will be asked to compile an app
// living in the system image. This may be a valid request - if the app wasn't compiled,
@@ -439,9 +470,12 @@
// (This is ugly as it's the only thing where we need to understand the contents
// of parameters_, but it beats postponing the decision or using the call-
// backs to do weird things.)
+
+ // In addition, no need to preopt for "verify". The existing vdex files in the OTA package
+ // and the /data partition will still be usable after the OTA update is applied.
const char* apk_path = parameters_.apk_path;
CHECK(apk_path != nullptr);
- if (StartsWith(apk_path, android_root_)) {
+ if (StartsWith(apk_path, android_root_) || !IsAotCompilation()) {
const char* last_slash = strrchr(apk_path, '/');
if (last_slash != nullptr) {
std::string path(apk_path, last_slash - apk_path + 1);
@@ -471,13 +505,18 @@
// TODO(calin): embed the profile name in the parameters.
int Dexopt() {
std::string error;
+
+ int dexopt_flags = parameters_.dexopt_flags;
+ // Make sure dex2oat is run with background priority.
+ dexopt_flags |= DEXOPT_BOOTCOMPLETE | DEXOPT_IDLE_BACKGROUND_JOB;
+
int res = dexopt(parameters_.apk_path,
parameters_.uid,
parameters_.pkgName,
parameters_.instruction_set,
parameters_.dexopt_needed,
parameters_.oat_dir,
- parameters_.dexopt_flags,
+ dexopt_flags,
parameters_.compiler_filter,
parameters_.volume_uuid,
parameters_.shared_libraries,
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index db5c34e..e483d54 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -72,7 +72,6 @@
PROGRESS=$(cmd otadexopt progress)
print -u${STATUS_FD} "global_progress $PROGRESS"
- sleep 1
i=$((i+1))
done
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index fb69513..d73a30b 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -93,22 +93,9 @@
libfuzzer_options: [
"max_len=50000",
],
- },
-}
-
-// Adding this new fuzzer to test the corpus generated by record_binder
-cc_fuzz {
- name: "servicemanager_test_fuzzer",
- defaults: [
- "servicemanager_defaults",
- "service_fuzzer_defaults",
- ],
- host_supported: true,
- srcs: ["fuzzers/ServiceManagerTestFuzzer.cpp"],
- fuzz_config: {
- libfuzzer_options: [
- "max_len=50000",
+ cc: [
+ "smoreland@google.com",
+ "waghpawan@google.com",
],
},
- corpus: ["fuzzers/servicemamanager_fuzzer_corpus/*"],
}
diff --git a/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp b/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp
deleted file mode 100644
index e19b6eb..0000000
--- a/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2023 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 <fuzzbinder/libbinder_driver.h>
-#include <utils/StrongPointer.h>
-
-#include "Access.h"
-#include "ServiceManager.h"
-
-using ::android::Access;
-using ::android::Parcel;
-using ::android::ServiceManager;
-using ::android::sp;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider provider(data, size);
- auto accessPtr = std::make_unique<Access>();
- auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr));
-
- // Reserved bytes
- provider.ConsumeBytes<uint8_t>(8);
- uint32_t code = provider.ConsumeIntegral<uint32_t>();
- uint32_t flag = provider.ConsumeIntegral<uint32_t>();
- std::vector<uint8_t> parcelData = provider.ConsumeRemainingBytes<uint8_t>();
-
- Parcel inputParcel;
- inputParcel.setData(parcelData.data(), parcelData.size());
-
- Parcel reply;
- serviceManager->transact(code, inputParcel, &reply, flag);
-
- serviceManager->clear();
-
- return 0;
-}
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2
deleted file mode 100644
index e69ab49..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36
deleted file mode 100644
index 88ad474..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37
deleted file mode 100644
index fae15a2..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39
deleted file mode 100644
index b326907..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4
deleted file mode 100644
index 05b27bf..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41
deleted file mode 100644
index b326907..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42
deleted file mode 100644
index cdaa1f0..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43
deleted file mode 100644
index ff0941b..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44
deleted file mode 100644
index cdaa1f0..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46
deleted file mode 100644
index 7e5f948..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8
deleted file mode 100644
index 07319f8..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8
+++ /dev/null
Binary files differ
diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9
deleted file mode 100644
index 39e5104..0000000
--- a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9
+++ /dev/null
Binary files differ
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index d36ebac..672d6cf 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -97,34 +97,12 @@
crate_name: "binder_ndk_bindgen",
wrapper_src: "sys/BinderBindings.hpp",
source_stem: "bindings",
- bindgen_flags: [
+ bindgen_flag_files: [
// Unfortunately the only way to specify the rust_non_exhaustive enum
// style for a type is to make it the default
- "--default-enum-style",
- "rust_non_exhaustive",
// and then specify constified enums for the enums we don't want
// rustified
- "--constified-enum",
- "android::c_interface::consts::.*",
-
- "--allowlist-type",
- "android::c_interface::.*",
- "--allowlist-type",
- "AStatus",
- "--allowlist-type",
- "AIBinder_Class",
- "--allowlist-type",
- "AIBinder",
- "--allowlist-type",
- "AIBinder_Weak",
- "--allowlist-type",
- "AIBinder_DeathRecipient",
- "--allowlist-type",
- "AParcel",
- "--allowlist-type",
- "binder_status_t",
- "--allowlist-function",
- ".*",
+ "libbinder_ndk_bindgen_flags.txt",
],
shared_libs: [
"libbinder_ndk",
diff --git a/libs/binder/rust/libbinder_ndk_bindgen_flags.txt b/libs/binder/rust/libbinder_ndk_bindgen_flags.txt
new file mode 100644
index 0000000..551c59f
--- /dev/null
+++ b/libs/binder/rust/libbinder_ndk_bindgen_flags.txt
@@ -0,0 +1,11 @@
+--default-enum-style=rust_non_exhaustive
+--constified-enum=android::c_interface::consts::.*
+--allowlist-type=android::c_interface::.*
+--allowlist-type=AStatus
+--allowlist-type=AIBinder_Class
+--allowlist-type=AIBinder
+--allowlist-type=AIBinder_Weak
+--allowlist-type=AIBinder_DeathRecipient
+--allowlist-type=AParcel
+--allowlist-type=binder_status_t
+--allowlist-function=.*
diff --git a/libs/binder/rust/src/error.rs b/libs/binder/rust/src/error.rs
index 8d9ce0e..eb04cc3 100644
--- a/libs/binder/rust/src/error.rs
+++ b/libs/binder/rust/src/error.rs
@@ -370,6 +370,94 @@
}
}
+/// A conversion from `std::result::Result<T, E>` to `binder::Result<T>`. If this type is `Ok(T)`,
+/// it's returned as is. If this type is `Err(E)`, `E` is converted into `Status` which can be
+/// either a general binder exception, or a service-specific exception.
+///
+/// # Examples
+///
+/// ```
+/// // std::io::Error is formatted as the exception's message
+/// fn file_exists(name: &str) -> binder::Result<bool> {
+/// std::fs::metadata(name)
+/// .or_service_specific_exception(NOT_FOUND)?
+/// }
+///
+/// // A custom function is used to create the exception's message
+/// fn file_exists(name: &str) -> binder::Result<bool> {
+/// std::fs::metadata(name)
+/// .or_service_specific_exception_with(NOT_FOUND,
+/// |e| format!("file {} not found: {:?}", name, e))?
+/// }
+///
+/// // anyhow::Error is formatted as the exception's message
+/// use anyhow::{Context, Result};
+/// fn file_exists(name: &str) -> binder::Result<bool> {
+/// std::fs::metadata(name)
+/// .context("file {} not found")
+/// .or_service_specific_exception(NOT_FOUND)?
+/// }
+///
+/// // General binder exceptions can be created similarly
+/// fn file_exists(name: &str) -> binder::Result<bool> {
+/// std::fs::metadata(name)
+/// .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?
+/// }
+/// ```
+pub trait IntoBinderResult<T, E> {
+ /// Converts the embedded error into a general binder exception of code `exception`. The
+ /// message of the exception is set by formatting the error for debugging.
+ fn or_binder_exception(self, exception: ExceptionCode) -> result::Result<T, Status>;
+
+ /// Converts the embedded error into a general binder exception of code `exception`. The
+ /// message of the exception is set by lazily evaluating the `op` function.
+ fn or_binder_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>(
+ self,
+ exception: ExceptionCode,
+ op: O,
+ ) -> result::Result<T, Status>;
+
+ /// Converts the embedded error into a service-specific binder exception. `error_code` is used
+ /// to distinguish different service-specific binder exceptions. The message of the exception
+ /// is set by formatting the error for debugging.
+ fn or_service_specific_exception(self, error_code: i32) -> result::Result<T, Status>;
+
+ /// Converts the embedded error into a service-specific binder exception. `error_code` is used
+ /// to distinguish different service-specific binder exceptions. The message of the exception
+ /// is set by lazily evaluating the `op` function.
+ fn or_service_specific_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>(
+ self,
+ error_code: i32,
+ op: O,
+ ) -> result::Result<T, Status>;
+}
+
+impl<T, E: std::fmt::Debug> IntoBinderResult<T, E> for result::Result<T, E> {
+ fn or_binder_exception(self, exception: ExceptionCode) -> result::Result<T, Status> {
+ self.or_binder_exception_with(exception, |e| format!("{:?}", e))
+ }
+
+ fn or_binder_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>(
+ self,
+ exception: ExceptionCode,
+ op: O,
+ ) -> result::Result<T, Status> {
+ self.map_err(|e| Status::new_exception_str(exception, Some(op(e))))
+ }
+
+ fn or_service_specific_exception(self, error_code: i32) -> result::Result<T, Status> {
+ self.or_service_specific_exception_with(error_code, |e| format!("{:?}", e))
+ }
+
+ fn or_service_specific_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>(
+ self,
+ error_code: i32,
+ op: O,
+ ) -> result::Result<T, Status> {
+ self.map_err(|e| Status::new_service_specific_error_str(error_code, Some(op(e))))
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -406,4 +494,66 @@
assert_eq!(status.service_specific_error(), 0);
assert_eq!(status.get_description(), "Status(-5, EX_ILLEGAL_STATE): ''".to_string());
}
+
+ #[test]
+ fn convert_to_service_specific_exception() {
+ let res: std::result::Result<(), Status> =
+ Err("message").or_service_specific_exception(-42);
+
+ assert!(res.is_err());
+ let status = res.unwrap_err();
+ assert_eq!(status.exception_code(), ExceptionCode::SERVICE_SPECIFIC);
+ assert_eq!(status.service_specific_error(), -42);
+ assert_eq!(
+ status.get_description(),
+ "Status(-8, EX_SERVICE_SPECIFIC): '-42: \"message\"'".to_string()
+ );
+ }
+
+ #[test]
+ fn convert_to_service_specific_exception_with() {
+ let res: std::result::Result<(), Status> = Err("message")
+ .or_service_specific_exception_with(-42, |e| format!("outer message: {:?}", e));
+
+ assert!(res.is_err());
+ let status = res.unwrap_err();
+ assert_eq!(status.exception_code(), ExceptionCode::SERVICE_SPECIFIC);
+ assert_eq!(status.service_specific_error(), -42);
+ assert_eq!(
+ status.get_description(),
+ "Status(-8, EX_SERVICE_SPECIFIC): '-42: outer message: \"message\"'".to_string()
+ );
+ }
+
+ #[test]
+ fn convert_to_binder_exception() {
+ let res: std::result::Result<(), Status> =
+ Err("message").or_binder_exception(ExceptionCode::ILLEGAL_STATE);
+
+ assert!(res.is_err());
+ let status = res.unwrap_err();
+ assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE);
+ assert_eq!(status.service_specific_error(), 0);
+ assert_eq!(
+ status.get_description(),
+ "Status(-5, EX_ILLEGAL_STATE): '\"message\"'".to_string()
+ );
+ }
+
+ #[test]
+ fn convert_to_binder_exception_with() {
+ let res: std::result::Result<(), Status> = Err("message")
+ .or_binder_exception_with(ExceptionCode::ILLEGAL_STATE, |e| {
+ format!("outer message: {:?}", e)
+ });
+
+ assert!(res.is_err());
+ let status = res.unwrap_err();
+ assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE);
+ assert_eq!(status.service_specific_error(), 0);
+ assert_eq!(
+ status.get_description(),
+ "Status(-5, EX_ILLEGAL_STATE): 'outer message: \"message\"'".to_string()
+ );
+ }
}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 0c8b48f..8841fe6 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -106,7 +106,7 @@
pub use crate::binder_async::{BinderAsyncPool, BoxFuture};
pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak};
-pub use error::{ExceptionCode, Status, StatusCode};
+pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode};
pub use native::{
add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service,
LazyServiceGuard,
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 41856f9..cd3e7c0 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -77,6 +77,8 @@
static_libs: [
"binderRecordReplayTestIface-cpp",
"binderReadParcelIface-cpp",
+ "libbinder_random_parcel_seeds",
+ "libbinder_random_parcel",
],
test_suites: ["general-tests"],
require_root: true,
diff --git a/libs/binder/tests/binderRecordReplayTest.cpp b/libs/binder/tests/binderRecordReplayTest.cpp
index 17d5c8a..6773c95 100644
--- a/libs/binder/tests/binderRecordReplayTest.cpp
+++ b/libs/binder/tests/binderRecordReplayTest.cpp
@@ -15,6 +15,7 @@
*/
#include <BnBinderRecordReplayTest.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <binder/Binder.h>
@@ -23,6 +24,11 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/RecordedTransaction.h>
+
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <fuzzseeds/random_parcel_seeds.h>
+
#include <gtest/gtest.h>
#include <sys/prctl.h>
@@ -30,6 +36,7 @@
#include "parcelables/SingleDataParcelable.h"
using namespace android;
+using android::generateSeedsFromRecording;
using android::binder::Status;
using android::binder::debug::RecordedTransaction;
using parcelables::SingleDataParcelable;
@@ -84,6 +91,44 @@
GENERATE_GETTER_SETTER(SingleDataParcelableArray, std::vector<SingleDataParcelable>);
};
+std::vector<uint8_t> retrieveData(base::borrowed_fd fd) {
+ struct stat fdStat;
+ EXPECT_TRUE(fstat(fd.get(), &fdStat) != -1);
+ EXPECT_TRUE(fdStat.st_size != 0);
+
+ std::vector<uint8_t> buffer(fdStat.st_size);
+ auto readResult = android::base::ReadFully(fd, buffer.data(), fdStat.st_size);
+ EXPECT_TRUE(readResult != 0);
+ return std::move(buffer);
+}
+
+void replayFuzzService(const sp<BpBinder>& binder, const RecordedTransaction& transaction) {
+ base::unique_fd seedFd(open("/data/local/tmp/replayFuzzService",
+ O_RDWR | O_CREAT | O_CLOEXEC | O_TRUNC, 0666));
+ ASSERT_TRUE(seedFd.ok());
+
+ // generate corpus from this transaction.
+ generateSeedsFromRecording(seedFd, transaction);
+
+ // Read the data which has been written to seed corpus
+ ASSERT_EQ(0, lseek(seedFd.get(), 0, SEEK_SET));
+ std::vector<uint8_t> seedData = retrieveData(seedFd);
+
+ // use fuzzService to replay the corpus
+ FuzzedDataProvider provider(seedData.data(), seedData.size());
+ fuzzService(binder, std::move(provider));
+}
+
+void replayBinder(const sp<BpBinder>& binder, const RecordedTransaction& transaction) {
+ // TODO: move logic to replay RecordedTransaction into RecordedTransaction
+ Parcel data;
+ data.setData(transaction.getDataParcel().data(), transaction.getDataParcel().dataSize());
+ auto result = binder->transact(transaction.getCode(), data, nullptr, transaction.getFlags());
+
+ // make sure recording does the thing we expect it to do
+ EXPECT_EQ(OK, result);
+}
+
class BinderRecordReplayTest : public ::testing::Test {
public:
void SetUp() override {
@@ -98,48 +143,46 @@
template <typename T, typename U>
void recordReplay(Status (IBinderRecordReplayTest::*set)(T), U recordedValue,
Status (IBinderRecordReplayTest::*get)(U*), U changedValue) {
- base::unique_fd fd(open("/data/local/tmp/binderRecordReplayTest.rec",
- O_RDWR | O_CREAT | O_CLOEXEC, 0666));
- ASSERT_TRUE(fd.ok());
+ auto replayFunctions = {&replayBinder, &replayFuzzService};
+ for (auto replayFunc : replayFunctions) {
+ base::unique_fd fd(open("/data/local/tmp/binderRecordReplayTest.rec",
+ O_RDWR | O_CREAT | O_CLOEXEC, 0666));
+ ASSERT_TRUE(fd.ok());
- // record a transaction
- mBpBinder->startRecordingBinder(fd);
- auto status = (*mInterface.*set)(recordedValue);
- EXPECT_TRUE(status.isOk());
- mBpBinder->stopRecordingBinder();
+ // record a transaction
+ mBpBinder->startRecordingBinder(fd);
+ auto status = (*mInterface.*set)(recordedValue);
+ EXPECT_TRUE(status.isOk());
+ mBpBinder->stopRecordingBinder();
- // test transaction does the thing we expect it to do
- U output;
- status = (*mInterface.*get)(&output);
- EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, recordedValue);
+ // test transaction does the thing we expect it to do
+ U output;
+ status = (*mInterface.*get)(&output);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_EQ(output, recordedValue);
- // write over the existing state
- status = (*mInterface.*set)(changedValue);
- EXPECT_TRUE(status.isOk());
+ // write over the existing state
+ status = (*mInterface.*set)(changedValue);
+ EXPECT_TRUE(status.isOk());
- status = (*mInterface.*get)(&output);
- EXPECT_TRUE(status.isOk());
+ status = (*mInterface.*get)(&output);
+ EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, changedValue);
+ EXPECT_EQ(output, changedValue);
- // replay transaction
- ASSERT_EQ(0, lseek(fd.get(), 0, SEEK_SET));
- std::optional<RecordedTransaction> transaction = RecordedTransaction::fromFile(fd);
- ASSERT_NE(transaction, std::nullopt);
+ // replay transaction
+ ASSERT_EQ(0, lseek(fd.get(), 0, SEEK_SET));
+ std::optional<RecordedTransaction> transaction = RecordedTransaction::fromFile(fd);
+ ASSERT_NE(transaction, std::nullopt);
- // TODO: move logic to replay RecordedTransaction into RecordedTransaction
- Parcel data;
- data.setData(transaction->getDataParcel().data(), transaction->getDataParcel().dataSize());
- auto result =
- mBpBinder->transact(transaction->getCode(), data, nullptr, transaction->getFlags());
+ const RecordedTransaction& recordedTransaction = *transaction;
+ // call replay function with recorded transaction
+ (*replayFunc)(mBpBinder, recordedTransaction);
- // make sure recording does the thing we expect it to do
- EXPECT_EQ(OK, result);
-
- status = (*mInterface.*get)(&output);
- EXPECT_TRUE(status.isOk());
- EXPECT_EQ(output, recordedValue);
+ status = (*mInterface.*get)(&output);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_EQ(output, recordedValue);
+ }
}
private:
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 35866ad..0d1503e 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -104,3 +104,28 @@
local_include_dirs: ["include_random_parcel"],
export_include_dirs: ["include_random_parcel"],
}
+
+cc_library {
+ name: "libbinder_random_parcel_seeds",
+ host_supported: true,
+ vendor_available: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ srcs: [
+ "random_parcel_seeds.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libbinder_ndk",
+ "libcutils",
+ "libutils",
+ ],
+ local_include_dirs: [
+ "include_random_parcel_seeds",
+ ],
+ export_include_dirs: ["include_random_parcel_seeds"],
+}
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h
new file mode 100644
index 0000000..5755239
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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 <android-base/file.h>
+#include <android-base/hex.h>
+#include <android-base/logging.h>
+
+#include <binder/Binder.h>
+#include <binder/Parcel.h>
+#include <binder/RecordedTransaction.h>
+
+#include <private/android_filesystem_config.h>
+
+#include <vector>
+
+using android::Parcel;
+using android::base::HexString;
+using std::vector;
+
+namespace android {
+namespace impl {
+// computes the bytes so that if they are passed to FuzzedDataProvider and
+// provider.ConsumeIntegralInRange<T>(min, max) is called, it will return val
+template <typename T>
+void writeReversedBuffer(std::vector<std::byte>& integralBuffer, T min, T max, T val);
+
+// Calls writeInBuffer method with min and max numeric limits of type T. This method
+// is reversal of ConsumeIntegral<T>() in FuzzedDataProvider
+template <typename T>
+void writeReversedBuffer(std::vector<std::byte>& integralBuffer, T val);
+} // namespace impl
+void generateSeedsFromRecording(base::borrowed_fd fd,
+ const binder::debug::RecordedTransaction& transaction);
+} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index b268c5d..47d2a0a 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -35,6 +35,11 @@
.extraFds = {},
};
+ // Reserved bytes so that we don't have to change fuzzers and seed corpus if
+ // we introduce anything new in fuzzService.
+ std::vector<uint8_t> reservedBytes = provider.ConsumeBytes<uint8_t>(8);
+ (void)reservedBytes;
+
// always refresh the calling identity, because we sometimes set it below, but also,
// the code we're fuzzing might reset it
IPCThreadState::self()->clearCallingIdentity();
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
new file mode 100644
index 0000000..9e3e2ab
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2023 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 <android-base/file.h>
+#include <android-base/logging.h>
+
+#include <binder/RecordedTransaction.h>
+
+#include <fuzzseeds/random_parcel_seeds.h>
+
+using android::base::WriteFully;
+
+namespace android {
+namespace impl {
+template <typename T>
+std::vector<uint8_t> reverseBytes(T min, T max, T val) {
+ uint64_t range = static_cast<uint64_t>(max) - min;
+ uint64_t result = val - min;
+ size_t offset = 0;
+
+ std::vector<uint8_t> reverseData;
+ uint8_t reversed = 0;
+ reversed |= result;
+
+ while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0) {
+ reverseData.push_back(reversed);
+ reversed = 0;
+ reversed |= (result >> CHAR_BIT);
+ result = result >> CHAR_BIT;
+ offset += CHAR_BIT;
+ }
+
+ return std::move(reverseData);
+}
+
+template <typename T>
+void writeReversedBuffer(std::vector<uint8_t>& integralBuffer, T min, T max, T val) {
+ std::vector<uint8_t> reversedData = reverseBytes(min, max, val);
+ // ConsumeIntegral Calls read buffer from the end. Keep inserting at the front of the buffer
+ // so that we can align fuzzService operations with seed generation for readability.
+ integralBuffer.insert(integralBuffer.begin(), reversedData.begin(), reversedData.end());
+}
+
+template <typename T>
+void writeReversedBuffer(std::vector<uint8_t>& integralBuffer, T val) {
+ // For ConsumeIntegral<T>() calls, FuzzedDataProvider uses numeric limits min and max
+ // as range
+ writeReversedBuffer(integralBuffer, std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max(), val);
+}
+
+} // namespace impl
+
+void generateSeedsFromRecording(base::borrowed_fd fd,
+ const binder::debug::RecordedTransaction& transaction) {
+ // Write Reserved bytes for future use
+ std::vector<uint8_t> reservedBytes(8);
+ CHECK(WriteFully(fd, reservedBytes.data(), reservedBytes.size())) << fd.get();
+
+ std::vector<uint8_t> integralBuffer;
+
+ // Write UID array : Array elements are initialized in the order that they are declared
+ // UID array index 2 element
+ // int64_t aidRoot = 0;
+ impl::writeReversedBuffer(integralBuffer, static_cast<int64_t>(AID_ROOT) << 32,
+ static_cast<int64_t>(AID_USER) << 32,
+ static_cast<int64_t>(AID_ROOT) << 32);
+
+ // UID array index 3 element
+ impl::writeReversedBuffer(integralBuffer, static_cast<int64_t>(AID_ROOT) << 32);
+
+ // always pick AID_ROOT -> index 0
+ size_t uidIndex = 0;
+ impl::writeReversedBuffer(integralBuffer, static_cast<size_t>(0), static_cast<size_t>(3),
+ uidIndex);
+
+ // Never set uid in seed corpus
+ uint8_t writeUid = 0;
+ impl::writeReversedBuffer(integralBuffer, writeUid);
+
+ // Read random code. this will be from recorded transaction
+ uint8_t selectCode = 1;
+ impl::writeReversedBuffer(integralBuffer, selectCode);
+
+ // Get from recorded transaction
+ uint32_t code = transaction.getCode();
+ impl::writeReversedBuffer(integralBuffer, code);
+
+ // Get from recorded transaction
+ uint32_t flags = transaction.getFlags();
+ impl::writeReversedBuffer(integralBuffer, flags);
+
+ // always fuzz primary binder
+ size_t extraBindersIndex = 0;
+ impl::writeReversedBuffer(integralBuffer, static_cast<size_t>(0), static_cast<size_t>(0),
+ extraBindersIndex);
+
+ const Parcel& dataParcel = transaction.getDataParcel();
+
+ // This buffer holds the bytes which will be used for fillRandomParcel API
+ std::vector<uint8_t> fillParcelBuffer;
+
+ // Don't take rpc path
+ uint8_t rpcBranch = 0;
+ impl::writeReversedBuffer(fillParcelBuffer, rpcBranch);
+
+ // Implicit branch on this path -> options->writeHeader(p, provider)
+ uint8_t writeHeaderInternal = 0;
+ impl::writeReversedBuffer(fillParcelBuffer, writeHeaderInternal);
+
+ // Choose to write data in parcel
+ size_t fillFuncIndex = 0;
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), static_cast<size_t>(2),
+ fillFuncIndex);
+
+ // Write parcel data size from recorded transaction
+ size_t toWrite = transaction.getDataParcel().dataBufferSize();
+ impl::writeReversedBuffer(fillParcelBuffer, static_cast<size_t>(0), toWrite, toWrite);
+
+ // Write parcel data with size towrite from recorded transaction
+ CHECK(WriteFully(fd, dataParcel.data(), toWrite)) << fd.get();
+
+ // Write Fill Parcel buffer size in integralBuffer so that fuzzService knows size of data
+ size_t subDataSize = toWrite + fillParcelBuffer.size();
+ impl::writeReversedBuffer(integralBuffer, static_cast<size_t>(0), subDataSize, subDataSize);
+
+ // Write fill parcel buffer
+ CHECK(WriteFully(fd, fillParcelBuffer.data(), fillParcelBuffer.size())) << fd.get();
+
+ // Write the integralBuffer to data
+ CHECK(WriteFully(fd, integralBuffer.data(), integralBuffer.size())) << fd.get();
+}
+} // namespace android
diff --git a/libs/fakeservicemanager/FakeServiceManager.cpp b/libs/fakeservicemanager/FakeServiceManager.cpp
index 3272bbc..80661c1 100644
--- a/libs/fakeservicemanager/FakeServiceManager.cpp
+++ b/libs/fakeservicemanager/FakeServiceManager.cpp
@@ -26,6 +26,8 @@
}
sp<IBinder> FakeServiceManager::checkService( const String16& name) const {
+ std::lock_guard<std::mutex> l(mMutex);
+
auto it = mNameToService.find(name);
if (it == mNameToService.end()) {
return nullptr;
@@ -36,6 +38,8 @@
status_t FakeServiceManager::addService(const String16& name, const sp<IBinder>& service,
bool /*allowIsolated*/,
int /*dumpsysFlags*/) {
+ std::lock_guard<std::mutex> l(mMutex);
+
if (service == nullptr) {
return UNEXPECTED_NULL;
}
@@ -44,6 +48,8 @@
}
Vector<String16> FakeServiceManager::listServices(int /*dumpsysFlags*/) {
+ std::lock_guard<std::mutex> l(mMutex);
+
Vector<String16> services;
for (auto const& [name, service] : mNameToService) {
(void) service;
@@ -61,10 +67,14 @@
}
bool FakeServiceManager::isDeclared(const String16& name) {
+ std::lock_guard<std::mutex> l(mMutex);
+
return mNameToService.find(name) != mNameToService.end();
}
Vector<String16> FakeServiceManager::getDeclaredInstances(const String16& name) {
+ std::lock_guard<std::mutex> l(mMutex);
+
Vector<String16> out;
const String16 prefix = name + String16("/");
for (const auto& [registeredName, service] : mNameToService) {
@@ -108,6 +118,8 @@
}
void FakeServiceManager::clear() {
+ std::lock_guard<std::mutex> l(mMutex);
+
mNameToService.clear();
}
} // namespace android
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
index 97add24..f62241d 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/FakeServiceManager.h
@@ -19,6 +19,7 @@
#include <binder/IServiceManager.h>
#include <map>
+#include <mutex>
#include <optional>
#include <vector>
@@ -68,6 +69,7 @@
void clear();
private:
+ mutable std::mutex mMutex;
std::map<String16, sp<IBinder>> mNameToService;
};
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 40061cd..9f814f1 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -176,11 +176,8 @@
mSensors = mSensorServer->getSensorList(mOpPackageName);
size_t count = mSensors.size();
- if (count == 0) {
- ALOGE("Failed to get Sensor list");
- mSensorServer.clear();
- return UNKNOWN_ERROR;
- }
+ // If count is 0, mSensorList will be non-null. This is old
+ // existing behavior and callers expect this.
mSensorList =
static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
LOG_ALWAYS_FATAL_IF(mSensorList == nullptr, "mSensorList NULL");