Add check for hidl package root hash.
When compiling a module, say foo.bar.baz@1.0::IBaz, assume the package
root is foo.bar:some/dir/interfaces, then:
- look at the file some/dir/interfaces/current.txt
- read hash from file corresponding from foo.bar.baz@1.0::IBaz
- file supports same-line comments with '#'
- format of file is each line is blank or looks like:
"<sha-256 hash> <fqName>"
- if the file is misformed or the hal does not match a sha in that file,
then it is considered build breakage.
Test: build with and without changing frozen files
Bug: 34178341
Change-Id: Ieddbc796ea974ac7c2e8b95ca69009c31e0cfb60
diff --git a/Coordinator.cpp b/Coordinator.cpp
index 72c8557..dee56aa 100644
--- a/Coordinator.cpp
+++ b/Coordinator.cpp
@@ -26,6 +26,7 @@
#include <hidl-util/StringHelper.h>
#include "AST.h"
+#include "Hash.h"
#include "Interface.h"
extern android::status_t parseFile(android::AST *ast);
@@ -378,7 +379,14 @@
}
// enforce all rules.
- status_t err = enforceMinorVersionUprevs(package);
+ status_t err;
+
+ err = enforceMinorVersionUprevs(package);
+ if (err != OK) {
+ return err;
+ }
+
+ err = enforceHashes(package);
if (err != OK) {
return err;
}
@@ -491,6 +499,51 @@
return OK;
}
+status_t Coordinator::enforceHashes(const FQName ¤tPackage) {
+ status_t err = OK;
+ std::vector<FQName> packageInterfaces;
+ err = appendPackageInterfacesToVector(currentPackage, &packageInterfaces);
+ if (err != OK) {
+ return err;
+ }
+
+ for (const FQName ¤tFQName : packageInterfaces) {
+ AST *ast = parse(currentFQName);
+
+ if (ast == nullptr) {
+ err = UNKNOWN_ERROR;
+ continue;
+ }
+
+ std::string packageRootPath = getPackageRootPath(currentFQName);
+ std::string error;
+ std::vector<std::string> frozen = Hash::lookupHash(packageRootPath, currentFQName.string(), &error);
+
+ if (error.size() > 0) {
+ LOG(ERROR) << error;
+ err = UNKNOWN_ERROR;
+ continue;
+ }
+
+ // hash not define, interface not frozen
+ if (frozen.size() == 0) {
+ continue;
+ }
+
+ std::string currentHash = Hash::getHash(ast->getFilename()).hexString();
+
+ if(std::find(frozen.begin(), frozen.end(), currentHash) == frozen.end()) {
+ LOG(ERROR) << currentFQName.string() << " has hash " << currentHash
+ << " which does not match hash on record. This interface has "
+ << "been frozen. Do not change it!";
+ err = UNKNOWN_ERROR;
+ continue;
+ }
+ }
+
+ return err;
+}
+
// static
bool Coordinator::MakeParentHierarchy(const std::string &path) {
static const mode_t kMode = 0755;