Otapreopt: Introduce protocol version 10
In version 10, we no longer assume '&' for shared libraries of system
packages, instead expecting the package manager state to be precise
and correct.
Add translation code to parameter parsing. For prior versions, reject
commands that have '&' for shared libraries.
Bug: 115993344
Test: mmma frameworks/native/cmds/installd
Test: atest installd_otapreopt_test
Change-Id: I191f82839047e31303303b610583cc0d64c78177
diff --git a/cmds/installd/otapreopt_parameters.cpp b/cmds/installd/otapreopt_parameters.cpp
index cf3de01..b1ad8db 100644
--- a/cmds/installd/otapreopt_parameters.cpp
+++ b/cmds/installd/otapreopt_parameters.cpp
@@ -16,6 +16,8 @@
#include "otapreopt_parameters.h"
+#include <cstring>
+
#include <android-base/logging.h>
#include "dexopt.h"
@@ -248,6 +250,8 @@
case 8: num_args_expected = 16; break;
// Version 9 adds a new dexopt flag: DEXOPT_GENERATE_APP_IMAGE
case 9: num_args_expected = 16; break;
+ // Version 10 is a compatibility bump.
+ case 10: num_args_expected = 16; break;
default:
LOG(ERROR) << "Don't know how to read arguments for version " << version;
return false;
@@ -360,6 +364,15 @@
}
}
+ if (version < 10) {
+ // Do not accept '&' as shared libraries from versions prior to 10. These may lead
+ // to runtime crashes. The server side of version 10+ should send the correct
+ // context in almost all cases (e.g., only for actual shared packages).
+ if (shared_libraries != nullptr && std::string("&") == shared_libraries) {
+ return false;
+ }
+ }
+
return true;
}
diff --git a/cmds/installd/tests/installd_otapreopt_test.cpp b/cmds/installd/tests/installd_otapreopt_test.cpp
index b518507..66dd51e 100644
--- a/cmds/installd/tests/installd_otapreopt_test.cpp
+++ b/cmds/installd/tests/installd_otapreopt_test.cpp
@@ -114,11 +114,14 @@
case 7: return "7";
case 8: return "8";
case 9: return "9";
+ case 10: return "10";
}
return nullptr;
}
- std::vector<const char*> getArgs(uint32_t version, bool versioned) {
+ std::vector<const char*> getArgs(uint32_t version,
+ bool versioned,
+ const char* shared_libs = "shared.lib") {
std::vector<const char*> args;
args.push_back("otapreopt"); // "otapreopt"
args.push_back("a"); // slot
@@ -135,7 +138,7 @@
args.push_back("0"); // dexopt_flags
args.push_back("speed"); // filter
args.push_back("!"); // volume
- args.push_back("shared.lib"); // libs
+ args.push_back(shared_libs); // libs
if (version > 1) {
args.push_back("!"); // seinfo
@@ -159,9 +162,11 @@
return args;
}
- void VerifyReadArguments(uint32_t version, bool versioned) {
+ void VerifyReadArguments(uint32_t version,
+ bool versioned,
+ const char* shared_libs = "shared.lib") {
OTAPreoptParameters params;
- std::vector<const char*> args = getArgs(version, versioned);
+ std::vector<const char*> args = getArgs(version, versioned, shared_libs);
ASSERT_TRUE(params.ReadArguments(args.size() - 1, args.data()));
verifyPackageParameters(params, version, versioned, args.data());
}
@@ -199,6 +204,18 @@
VerifyReadArguments(7, true);
}
+TEST_F(OTAPreoptTest, ReadArgumentsV9SharedLibsAmpersand) {
+ OTAPreoptParameters params;
+ std::vector<const char*> args = getArgs(9, true, "&");
+ ASSERT_FALSE(params.ReadArguments(args.size() - 1, args.data()));
+}
+
+TEST_F(OTAPreoptTest, ReadArgumentsV10SharedLibsAmpersand) {
+ OTAPreoptParameters params;
+ std::vector<const char*> args = getArgs(10, true, "&");
+ ASSERT_TRUE(params.ReadArguments(args.size() - 1, args.data()));
+}
+
TEST_F(OTAPreoptTest, ReadArgumentsFailToManyArgs) {
OTAPreoptParameters params;
std::vector<const char*> args = getArgs(5, true);