diff options
-rw-r--r-- | Android.mk | 20 | ||||
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | tests/Android.mk | 35 | ||||
-rw-r--r-- | tests/component/verifier_test.cpp (renamed from verifier_test.cpp) | 167 | ||||
-rw-r--r-- | tests/testdata/alter-footer.zip (renamed from testdata/alter-footer.zip) | bin | 4009 -> 4009 bytes | |||
-rw-r--r-- | tests/testdata/alter-metadata.zip (renamed from testdata/alter-metadata.zip) | bin | 4009 -> 4009 bytes | |||
-rw-r--r-- | tests/testdata/fake-eocd.zip (renamed from testdata/fake-eocd.zip) | bin | 4313 -> 4313 bytes | |||
-rw-r--r-- | tests/testdata/jarsigned.zip (renamed from testdata/jarsigned.zip) | bin | 2271 -> 2271 bytes | |||
-rw-r--r-- | tests/testdata/otasigned.zip (renamed from testdata/otasigned.zip) | bin | 4009 -> 4009 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_ecdsa_sha256.zip (renamed from testdata/otasigned_ecdsa_sha256.zip) | bin | 3085 -> 3085 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_f4.zip (renamed from testdata/otasigned_f4.zip) | bin | 5195 -> 5195 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_f4_sha256.zip (renamed from testdata/otasigned_f4_sha256.zip) | bin | 5319 -> 5319 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_sha256.zip (renamed from testdata/otasigned_sha256.zip) | bin | 5326 -> 5326 bytes | |||
-rw-r--r-- | tests/testdata/random.zip (renamed from testdata/random.zip) | bin | 1024 -> 1024 bytes | |||
-rw-r--r-- | tests/testdata/test_f4.pk8 (renamed from testdata/test_f4.pk8) | bin | 1217 -> 1217 bytes | |||
-rw-r--r-- | tests/testdata/test_f4.x509.pem (renamed from testdata/test_f4.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/test_f4_sha256.x509.pem (renamed from testdata/test_f4_sha256.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey.pk8 (renamed from testdata/testkey.pk8) | bin | 1217 -> 1217 bytes | |||
-rw-r--r-- | tests/testdata/testkey.x509.pem (renamed from testdata/testkey.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_ecdsa.pk8 (renamed from testdata/testkey_ecdsa.pk8) | bin | 138 -> 138 bytes | |||
-rw-r--r-- | tests/testdata/testkey_ecdsa.x509.pem (renamed from testdata/testkey_ecdsa.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_sha256.x509.pem (renamed from testdata/testkey_sha256.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/unsigned.zip (renamed from testdata/unsigned.zip) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | tests/unit/asn1_decoder_test.cpp (renamed from tests/asn1_decoder_test.cpp) | 0 | ||||
-rw-r--r-- | updater/install.cpp | 83 | ||||
-rwxr-xr-x | verifier_test.sh | 121 |
26 files changed, 184 insertions, 259 deletions
diff --git a/Android.mk b/Android.mk index 602a85673..a48980fe8 100644 --- a/Android.mk +++ b/Android.mk @@ -104,28 +104,10 @@ LOCAL_CLANG := true LOCAL_MODULE := libverifier LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := \ - asn1_decoder.cpp -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_CLANG := true -LOCAL_MODULE := verifier_test -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_TAGS := tests -LOCAL_CFLAGS += -Wno-unused-parameter -LOCAL_SRC_FILES := \ - verifier_test.cpp \ asn1_decoder.cpp \ verifier.cpp \ ui.cpp -LOCAL_STATIC_LIBRARIES := \ - libmincrypt \ - libminui \ - libminzip \ - libcutils \ - libc -include $(BUILD_EXECUTABLE) - +include $(BUILD_STATIC_LIBRARY) include $(LOCAL_PATH)/minui/Android.mk \ $(LOCAL_PATH)/minzip/Android.mk \ @@ -10,3 +10,20 @@ Quick turn-around testing # without flashing the recovery partition: adb reboot bootloader fastboot boot $ANDROID_PRODUCT_OUT/recovery.img + +Running the tests +----------------- + # After setting up environment and lunch. + mmma -j bootable/recovery + + # Running the tests on device. + adb root + adb sync data + + # 32-bit device + adb shell /data/nativetest/recovery_unit_test/recovery_unit_test + adb shell /data/nativetest/recovery_component_test/recovery_component_test + + # Or 64-bit device + adb shell /data/nativetest64/recovery_unit_test/recovery_unit_test + adb shell /data/nativetest64/recovery_component_test/recovery_component_test diff --git a/tests/Android.mk b/tests/Android.mk index 4ce00b457..3f3c433eb 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -16,11 +16,40 @@ LOCAL_PATH := $(call my-dir) +# Unit tests include $(CLEAR_VARS) LOCAL_CLANG := true +LOCAL_MODULE := recovery_unit_test LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_STATIC_LIBRARIES := libverifier -LOCAL_SRC_FILES := asn1_decoder_test.cpp -LOCAL_MODULE := asn1_decoder_test -LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. +LOCAL_SRC_FILES := unit/asn1_decoder_test.cpp +LOCAL_C_INCLUDES := bootable/recovery +include $(BUILD_NATIVE_TEST) + +# Component tests +include $(CLEAR_VARS) +LOCAL_CLANG := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk +LOCAL_MODULE := recovery_component_test +LOCAL_C_INCLUDES := bootable/recovery +LOCAL_SRC_FILES := component/verifier_test.cpp +LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_STATIC_LIBRARIES := \ + libbase \ + libverifier \ + libmincrypt \ + libminui \ + libminzip \ + libcutils \ + libc + +testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) +testdata_files := $(call find-subdir-files, testdata/*) + +GEN := $(addprefix $(testdata_out_path)/, $(testdata_files)) +$(GEN): PRIVATE_PATH := $(LOCAL_PATH) +$(GEN): PRIVATE_CUSTOM_TOOL = cp $< $@ +$(GEN): $(testdata_out_path)/% : $(LOCAL_PATH)/% + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) include $(BUILD_NATIVE_TEST) diff --git a/verifier_test.cpp b/tests/component/verifier_test.cpp index 2367e0052..7f7b1b448 100644 --- a/verifier_test.cpp +++ b/tests/component/verifier_test.cpp @@ -1,13 +1,13 @@ /* * Copyright (C) 2009 The Android Open Source Project * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 + * Unless required by applicable law or agree 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 @@ -16,22 +16,33 @@ #include <errno.h> #include <fcntl.h> -#include <stdarg.h> +#include <gtest/gtest.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <memory> +#include <string> #include <vector> +#include <android-base/stringprintf.h> + #include "common.h" -#include "verifier.h" -#include "ui.h" #include "mincrypt/sha.h" #include "mincrypt/sha256.h" #include "minzip/SysUtil.h" +#include "ui.h" +#include "verifier.h" + +#if defined(__LP64__) +#define NATIVE_TEST_PATH "/nativetest64" +#else +#define NATIVE_TEST_PATH "/nativetest" +#endif + +static const char* DATA_PATH = getenv("ANDROID_DATA"); +static const char* TESTDATA_PATH = "/recovery_component_test/testdata/"; // This is build/target/product/security/testkey.x509.pem after being // dumped out by dumpkey.jar. @@ -123,9 +134,7 @@ ECPublicKey test_ec_key = RecoveryUI* ui = NULL; -// verifier expects to find a UI object; we provide one that does -// nothing but print. -class FakeUI : public RecoveryUI { +class MockUI : public RecoveryUI { void Init() { } void SetStage(int, int) { } void SetLocale(const char*) { } @@ -166,79 +175,93 @@ ui_print(const char* format, ...) { va_end(ap); } -int main(int argc, char** argv) { - if (argc < 2) { - fprintf(stderr, "Usage: %s [-sha256] [-ec | -f4 | -file <keys>] <package>\n", argv[0]); - return 2; - } - +class VerifierTest : public testing::TestWithParam<std::vector<std::string>> { + public: + MemMapping memmap; std::vector<Certificate> certs; - int argn = 1; - while (argn < argc) { - if (strcmp(argv[argn], "-sha256") == 0) { - if (certs.empty()) { - fprintf(stderr, "May only specify -sha256 after key type\n"); - return 2; + + virtual void SetUp() { + std::vector<std::string> args = GetParam(); + std::string package = android::base::StringPrintf("%s%s%s%s", DATA_PATH, NATIVE_TEST_PATH, + TESTDATA_PATH, args[0].c_str()); + for (auto it = ++(args.cbegin()); it != args.cend(); ++it) { + if (it->substr(it->length() - 3, it->length()) == "256") { + if (certs.empty()) { + FAIL() << "May only specify -sha256 after key type\n"; + } + certs.back().hash_len = SHA256_DIGEST_SIZE; + } else if (*it == "ec") { + certs.emplace_back(SHA_DIGEST_SIZE, Certificate::EC, + nullptr, std::unique_ptr<ECPublicKey>(new ECPublicKey(test_ec_key))); + } else if (*it == "e3") { + certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA, + std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_key)), nullptr); + } else if (*it == "f4") { + certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA, + std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_f4_key)), nullptr); } - ++argn; - certs.back().hash_len = SHA256_DIGEST_SIZE; - } else if (strcmp(argv[argn], "-ec") == 0) { - ++argn; - certs.emplace_back(SHA_DIGEST_SIZE, Certificate::EC, - nullptr, std::unique_ptr<ECPublicKey>(new ECPublicKey(test_ec_key))); - } else if (strcmp(argv[argn], "-e3") == 0) { - ++argn; + } + if (certs.empty()) { certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA, std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_key)), nullptr); - } else if (strcmp(argv[argn], "-f4") == 0) { - ++argn; - certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA, - std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_f4_key)), nullptr); - } else if (strcmp(argv[argn], "-file") == 0) { - if (!certs.empty()) { - fprintf(stderr, "Cannot specify -file with other certs specified\n"); - return 2; - } - ++argn; - if (!load_keys(argv[argn], certs)) { - fprintf(stderr, "Cannot load keys from %s\n", argv[argn]); - } - ++argn; - } else if (argv[argn][0] == '-') { - fprintf(stderr, "Unknown argument %s\n", argv[argn]); - return 2; - } else { - break; + } + if (sysMapFile(package.c_str(), &memmap) != 0) { + FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n"; } } - if (argn == argc) { - fprintf(stderr, "Must specify package to verify\n"); - return 2; + static void SetUpTestCase() { + ui = new MockUI(); } +}; - if (certs.empty()) { - certs.emplace_back(SHA_DIGEST_SIZE, Certificate::RSA, - std::unique_ptr<RSAPublicKey>(new RSAPublicKey(test_key)), nullptr); - } +class VerifierSuccessTest : public VerifierTest { +}; - ui = new FakeUI(); +class VerifierFailureTest : public VerifierTest { +}; - MemMapping map; - if (sysMapFile(argv[argn], &map) != 0) { - fprintf(stderr, "failed to mmap %s: %s\n", argv[argn], strerror(errno)); - return 4; - } +TEST_P(VerifierSuccessTest, VerifySucceed) { + ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_SUCCESS); +} - int result = verify_file(map.addr, map.length, certs); - if (result == VERIFY_SUCCESS) { - printf("VERIFIED\n"); - return 0; - } else if (result == VERIFY_FAILURE) { - printf("NOT VERIFIED\n"); - return 1; - } else { - printf("bad return value\n"); - return 3; - } +TEST_P(VerifierFailureTest, VerifyFailure) { + ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_FAILURE); } + +INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest, + ::testing::Values( + std::vector<std::string>({"otasigned.zip", "e3"}), + std::vector<std::string>({"otasigned_f4.zip", "f4"}), + std::vector<std::string>({"otasigned_sha256.zip", "e3", "sha256"}), + std::vector<std::string>({"otasigned_f4_sha256.zip", "f4", "sha256"}), + std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "ec", "sha256"}))); + +INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest, + ::testing::Values( + std::vector<std::string>({"otasigned.zip", "f4", "e3"}), + std::vector<std::string>({"otasigned_f4.zip", "ec", "f4"}), + std::vector<std::string>({"otasigned_sha256.zip", "ec", "e3", "e3", "sha256"}), + std::vector<std::string>({"otasigned_f4_sha256.zip", "ec", "sha256", "e3", "f4", "sha256"}), + std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "f4", "sha256", "e3", "ec", "sha256"}))); + +INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest, + ::testing::Values( + std::vector<std::string>({"otasigned.zip", "f4"}), + std::vector<std::string>({"otasigned_f4.zip", "e3"}), + std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "e3", "sha256"}))); + +INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest, + ::testing::Values( + std::vector<std::string>({"otasigned.zip", "e3", "sha256"}), + std::vector<std::string>({"otasigned_f4.zip", "f4", "sha256"}), + std::vector<std::string>({"otasigned_sha256.zip"}), + std::vector<std::string>({"otasigned_f4_sha256.zip", "f4"}), + std::vector<std::string>({"otasigned_ecdsa_sha256.zip"}))); + +INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest, + ::testing::Values( + std::vector<std::string>({"random.zip"}), + std::vector<std::string>({"fake-eocd.zip"}), + std::vector<std::string>({"alter-metadata.zip"}), + std::vector<std::string>({"alter-footer.zip"}))); diff --git a/testdata/alter-footer.zip b/tests/testdata/alter-footer.zip Binary files differindex f497ec000..f497ec000 100644 --- a/testdata/alter-footer.zip +++ b/tests/testdata/alter-footer.zip diff --git a/testdata/alter-metadata.zip b/tests/testdata/alter-metadata.zip Binary files differindex 1c71fbc49..1c71fbc49 100644 --- a/testdata/alter-metadata.zip +++ b/tests/testdata/alter-metadata.zip diff --git a/testdata/fake-eocd.zip b/tests/testdata/fake-eocd.zip Binary files differindex 15dc0a946..15dc0a946 100644 --- a/testdata/fake-eocd.zip +++ b/tests/testdata/fake-eocd.zip diff --git a/testdata/jarsigned.zip b/tests/testdata/jarsigned.zip Binary files differindex 8b1ef8bdd..8b1ef8bdd 100644 --- a/testdata/jarsigned.zip +++ b/tests/testdata/jarsigned.zip diff --git a/testdata/otasigned.zip b/tests/testdata/otasigned.zip Binary files differindex a6bc53e41..a6bc53e41 100644 --- a/testdata/otasigned.zip +++ b/tests/testdata/otasigned.zip diff --git a/testdata/otasigned_ecdsa_sha256.zip b/tests/testdata/otasigned_ecdsa_sha256.zip Binary files differindex 999fcdd0f..999fcdd0f 100644 --- a/testdata/otasigned_ecdsa_sha256.zip +++ b/tests/testdata/otasigned_ecdsa_sha256.zip diff --git a/testdata/otasigned_f4.zip b/tests/testdata/otasigned_f4.zip Binary files differindex dd1e4dd40..dd1e4dd40 100644 --- a/testdata/otasigned_f4.zip +++ b/tests/testdata/otasigned_f4.zip diff --git a/testdata/otasigned_f4_sha256.zip b/tests/testdata/otasigned_f4_sha256.zip Binary files differindex 3af408c40..3af408c40 100644 --- a/testdata/otasigned_f4_sha256.zip +++ b/tests/testdata/otasigned_f4_sha256.zip diff --git a/testdata/otasigned_sha256.zip b/tests/testdata/otasigned_sha256.zip Binary files differindex 0ed4409b3..0ed4409b3 100644 --- a/testdata/otasigned_sha256.zip +++ b/tests/testdata/otasigned_sha256.zip diff --git a/testdata/random.zip b/tests/testdata/random.zip Binary files differindex 18c0b3b9f..18c0b3b9f 100644 --- a/testdata/random.zip +++ b/tests/testdata/random.zip diff --git a/testdata/test_f4.pk8 b/tests/testdata/test_f4.pk8 Binary files differindex 3052613c5..3052613c5 100644 --- a/testdata/test_f4.pk8 +++ b/tests/testdata/test_f4.pk8 diff --git a/testdata/test_f4.x509.pem b/tests/testdata/test_f4.x509.pem index 814abcf99..814abcf99 100644 --- a/testdata/test_f4.x509.pem +++ b/tests/testdata/test_f4.x509.pem diff --git a/testdata/test_f4_sha256.x509.pem b/tests/testdata/test_f4_sha256.x509.pem index 9d5376b45..9d5376b45 100644 --- a/testdata/test_f4_sha256.x509.pem +++ b/tests/testdata/test_f4_sha256.x509.pem diff --git a/testdata/testkey.pk8 b/tests/testdata/testkey.pk8 Binary files differindex 586c1bd5c..586c1bd5c 100644 --- a/testdata/testkey.pk8 +++ b/tests/testdata/testkey.pk8 diff --git a/testdata/testkey.x509.pem b/tests/testdata/testkey.x509.pem index e242d83e2..e242d83e2 100644 --- a/testdata/testkey.x509.pem +++ b/tests/testdata/testkey.x509.pem diff --git a/testdata/testkey_ecdsa.pk8 b/tests/testdata/testkey_ecdsa.pk8 Binary files differindex 9a521c8cf..9a521c8cf 100644 --- a/testdata/testkey_ecdsa.pk8 +++ b/tests/testdata/testkey_ecdsa.pk8 diff --git a/testdata/testkey_ecdsa.x509.pem b/tests/testdata/testkey_ecdsa.x509.pem index b12283645..b12283645 100644 --- a/testdata/testkey_ecdsa.x509.pem +++ b/tests/testdata/testkey_ecdsa.x509.pem diff --git a/testdata/testkey_sha256.x509.pem b/tests/testdata/testkey_sha256.x509.pem index 002ce8968..002ce8968 100644 --- a/testdata/testkey_sha256.x509.pem +++ b/tests/testdata/testkey_sha256.x509.pem diff --git a/testdata/unsigned.zip b/tests/testdata/unsigned.zip Binary files differindex 24e3eadac..24e3eadac 100644 --- a/testdata/unsigned.zip +++ b/tests/testdata/unsigned.zip diff --git a/tests/asn1_decoder_test.cpp b/tests/unit/asn1_decoder_test.cpp index af96d87d2..af96d87d2 100644 --- a/tests/asn1_decoder_test.cpp +++ b/tests/unit/asn1_decoder_test.cpp diff --git a/updater/install.cpp b/updater/install.cpp index 5326b12a8..45bbf2bc1 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -34,6 +34,9 @@ #include <linux/xattr.h> #include <inttypes.h> +#include <memory> +#include <vector> + #include <android-base/parseint.h> #include <android-base/strings.h> #include <android-base/stringprintf.h> @@ -439,8 +442,7 @@ Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) { for (int i = 0; i < argc; ++i) { paths[i] = Evaluate(state, argv[i]); if (paths[i] == NULL) { - int j; - for (j = 0; j < i; ++i) { + for (int j = 0; j < i; ++j) { free(paths[j]); } free(paths); @@ -581,13 +583,13 @@ Value* PackageExtractFileFn(const char* name, State* state, // as the result. char* zip_path; + if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL; + Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); v->type = VAL_BLOB; v->size = -1; v->data = NULL; - if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL; - ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; const ZipEntry* entry = mzFindZipEntry(za, zip_path); if (entry == NULL) { @@ -1193,44 +1195,40 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { } int patchcount = (argc-4) / 2; - Value** patches = ReadValueVarArgs(state, argc-4, argv+4); + std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc-4, argv+4), + free); + if (!arg_values) { + return nullptr; + } + std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patch_shas; + std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patches; + // Protect values by unique_ptrs first to get rid of memory leak. + for (int i = 0; i < patchcount * 2; i += 2) { + patch_shas.emplace_back(arg_values.get()[i], FreeValue); + patches.emplace_back(arg_values.get()[i+1], FreeValue); + } - int i; - for (i = 0; i < patchcount; ++i) { - if (patches[i*2]->type != VAL_STRING) { + for (int i = 0; i < patchcount; ++i) { + if (patch_shas[i]->type != VAL_STRING) { ErrorAbort(state, "%s(): sha-1 #%d is not string", name, i); - break; + return nullptr; } - if (patches[i*2+1]->type != VAL_BLOB) { + if (patches[i]->type != VAL_BLOB) { ErrorAbort(state, "%s(): patch #%d is not blob", name, i); - break; + return nullptr; } } - if (i != patchcount) { - for (i = 0; i < patchcount*2; ++i) { - FreeValue(patches[i]); - } - free(patches); - return NULL; - } - char** patch_sha_str = reinterpret_cast<char**>(malloc(patchcount * sizeof(char*))); - for (i = 0; i < patchcount; ++i) { - patch_sha_str[i] = patches[i*2]->data; - patches[i*2]->data = NULL; - FreeValue(patches[i*2]); - patches[i] = patches[i*2+1]; + std::vector<char*> patch_sha_str; + std::vector<Value*> patch_ptrs; + for (int i = 0; i < patchcount; ++i) { + patch_sha_str.push_back(patch_shas[i]->data); + patch_ptrs.push_back(patches[i].get()); } int result = applypatch(source_filename, target_filename, target_sha1, target_size, - patchcount, patch_sha_str, patches, NULL); - - for (i = 0; i < patchcount; ++i) { - FreeValue(patches[i]); - } - free(patch_sha_str); - free(patches); + patchcount, patch_sha_str.data(), patch_ptrs.data(), NULL); return StringValue(strdup(result == 0 ? "t" : "")); } @@ -1349,9 +1347,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) { return ErrorAbort(state, "%s() expects at least 1 arg", name); } - Value** args = ReadValueVarArgs(state, argc, argv); - if (args == NULL) { - return NULL; + std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc, argv), free); + if (arg_values == nullptr) { + return nullptr; + } + std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> args; + for (int i = 0; i < argc; ++i) { + args.emplace_back(arg_values.get()[i], FreeValue); } if (args[0]->size < 0) { @@ -1359,14 +1361,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) { } uint8_t digest[SHA_DIGEST_LENGTH]; SHA1(reinterpret_cast<uint8_t*>(args[0]->data), args[0]->size, digest); - FreeValue(args[0]); if (argc == 1) { return StringValue(PrintSha1(digest)); } int i; - uint8_t* arg_digest = reinterpret_cast<uint8_t*>(malloc(SHA_DIGEST_LENGTH)); + uint8_t arg_digest[SHA_DIGEST_LENGTH]; for (i = 1; i < argc; ++i) { if (args[i]->type != VAL_STRING) { printf("%s(): arg %d is not a string; skipping", @@ -1378,19 +1379,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) { } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) { break; } - FreeValue(args[i]); } if (i >= argc) { // Didn't match any of the hex strings; return false. return StringValue(strdup("")); } - // Found a match; free all the remaining arguments and return the - // matched one. - int j; - for (j = i+1; j < argc; ++j) { - FreeValue(args[j]); - } - return args[i]; + // Found a match. + return args[i].release(); } // Read a local file and return its contents (the Value* returned diff --git a/verifier_test.sh b/verifier_test.sh deleted file mode 100755 index 4761cef4a..000000000 --- a/verifier_test.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/bash -# -# A test suite for recovery's package signature verifier. Run in a -# client where you have done envsetup, lunch, etc. -# -# TODO: find some way to get this run regularly along with the rest of -# the tests. - -EMULATOR_PORT=5580 -DATA_DIR=$ANDROID_BUILD_TOP/bootable/recovery/testdata - -WORK_DIR=/data/local/tmp - -# set to 0 to use a device instead -USE_EMULATOR=0 - -# ------------------------ - -if [ "$USE_EMULATOR" == 1 ]; then - emulator -wipe-data -noaudio -no-window -port $EMULATOR_PORT & - pid_emulator=$! - ADB="adb -s emulator-$EMULATOR_PORT " -else - ADB="adb -d " -fi - -echo "waiting to connect to device" -$ADB wait-for-device - -# run a command on the device; exit with the exit status of the device -# command. -run_command() { - $ADB shell "$@" \; echo \$? | awk '{if (b) {print a}; a=$0; b=1} END {exit a}' -} - -testname() { - echo - echo "::: testing $1 :::" - testname="$1" -} - -fail() { - echo - echo FAIL: $testname - echo - [ "$open_pid" == "" ] || kill $open_pid - [ "$pid_emulator" == "" ] || kill $pid_emulator - exit 1 -} - - -cleanup() { - # not necessary if we're about to kill the emulator, but nice for - # running on real devices or already-running emulators. - run_command rm $WORK_DIR/verifier_test - run_command rm $WORK_DIR/package.zip - - [ "$pid_emulator" == "" ] || kill $pid_emulator -} - -$ADB push $ANDROID_PRODUCT_OUT/system/bin/verifier_test \ - $WORK_DIR/verifier_test - -expect_succeed() { - testname "$1 (should succeed)" - $ADB push $DATA_DIR/$1 $WORK_DIR/package.zip - shift - run_command $WORK_DIR/verifier_test "$@" $WORK_DIR/package.zip || fail -} - -expect_fail() { - testname "$1 (should fail)" - $ADB push $DATA_DIR/$1 $WORK_DIR/package.zip - shift - run_command $WORK_DIR/verifier_test "$@" $WORK_DIR/package.zip && fail -} - -# not signed at all -expect_fail unsigned.zip -# signed in the pre-donut way -expect_fail jarsigned.zip - -# success cases -expect_succeed otasigned.zip -e3 -expect_succeed otasigned_f4.zip -f4 -expect_succeed otasigned_sha256.zip -e3 -sha256 -expect_succeed otasigned_f4_sha256.zip -f4 -sha256 -expect_succeed otasigned_ecdsa_sha256.zip -ec -sha256 - -# success with multiple keys -expect_succeed otasigned.zip -f4 -e3 -expect_succeed otasigned_f4.zip -ec -f4 -expect_succeed otasigned_sha256.zip -ec -e3 -e3 -sha256 -expect_succeed otasigned_f4_sha256.zip -ec -sha256 -e3 -f4 -sha256 -expect_succeed otasigned_ecdsa_sha256.zip -f4 -sha256 -e3 -ec -sha256 - -# verified against different key -expect_fail otasigned.zip -f4 -expect_fail otasigned_f4.zip -e3 -expect_fail otasigned_ecdsa_sha256.zip -e3 -sha256 - -# verified against right key but wrong hash algorithm -expect_fail otasigned.zip -e3 -sha256 -expect_fail otasigned_f4.zip -f4 -sha256 -expect_fail otasigned_sha256.zip -expect_fail otasigned_f4_sha256.zip -f4 -expect_fail otasigned_ecdsa_sha256.zip - -# various other cases -expect_fail random.zip -expect_fail fake-eocd.zip -expect_fail alter-metadata.zip -expect_fail alter-footer.zip - -# --------------- cleanup ---------------------- - -cleanup - -echo -echo PASS -echo |