summaryrefslogtreecommitdiff
path: root/libfec
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2016-10-19 15:58:13 -0700
committerSami Tolvanen <samitolvanen@google.com>2016-10-20 09:22:49 -0700
commitb5afa97f093e0b87614cb9e96a754f7c0e169c4f (patch)
tree83168b6fbc24b0b93f50219dd7b5be0abd940ea1 /libfec
parentb003c9c9ebf6aafd759f3dd7d19515d18f4a0180 (diff)
downloadextras-b5afa97f093e0b87614cb9e96a754f7c0e169c4f.tar.gz
libfec: correct verity table only if it's invalid
To increase reliability in the case where part of the partition is corrupt and error correction might fail, attempt to use raw verity table before the corrected one. Bug: 32288104 Test: tested on angler Change-Id: I201fdc6162c87b1808979486df5707d683a6d20c
Diffstat (limited to 'libfec')
-rw-r--r--libfec/fec_verity.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/libfec/fec_verity.cpp b/libfec/fec_verity.cpp
index 5dea53dd..3f636dd0 100644
--- a/libfec/fec_verity.cpp
+++ b/libfec/fec_verity.cpp
@@ -312,6 +312,11 @@ static int verify_tree(fec_handle *f, const uint8_t *root)
debug("valid");
+ if (v->hash) {
+ delete[] v->hash;
+ v->hash = NULL;
+ }
+
v->hash = data_hashes.release();
return 0;
}
@@ -319,7 +324,7 @@ static int verify_tree(fec_handle *f, const uint8_t *root)
/* reads, corrects and parses the verity table, validates parameters, and if
`f->flags' does not have `FEC_VERITY_DISABLE' set, calls `verify_tree' to
load and validate the hash tree */
-static int parse_table(fec_handle *f, uint64_t offset, uint32_t size)
+static int parse_table(fec_handle *f, uint64_t offset, uint32_t size, bool useecc)
{
check(f);
check(size >= VERITY_MIN_TABLE_SIZE);
@@ -335,8 +340,13 @@ static int parse_table(fec_handle *f, uint64_t offset, uint32_t size)
return -1;
}
- if (fec_pread(f, table.get(), size, offset) != (ssize_t)size) {
- error("failed to read verity table: %s", strerror(errno));
+ if (!useecc) {
+ if (!raw_pread(f, table.get(), size, offset)) {
+ error("failed to read verity table: %s", strerror(errno));
+ return -1;
+ }
+ } else if (fec_pread(f, table.get(), size, offset) != (ssize_t)size) {
+ error("failed to ecc read verity table: %s", strerror(errno));
return -1;
}
@@ -430,7 +440,18 @@ static int parse_table(fec_handle *f, uint64_t offset, uint32_t size)
check(v->data_blocks == v->hash_start / FEC_BLOCKSIZE);
}
+ if (v->salt) {
+ delete[] v->salt;
+ v->salt = NULL;
+ }
+
v->salt = salt.release();
+
+ if (v->table) {
+ delete[] v->table;
+ v->table = NULL;
+ }
+
v->table = table.release();
if (!(f->flags & FEC_VERITY_DISABLE)) {
@@ -589,7 +610,10 @@ int verity_parse_header(fec_handle *f, uint64_t offset)
v->metadata_start = offset;
- if (parse_table(f, offset + sizeof(v->header), v->header.length) == -1) {
+ if (parse_table(f, offset + sizeof(v->header), v->header.length,
+ false) == -1 &&
+ parse_table(f, offset + sizeof(v->header), v->header.length,
+ true) == -1) {
return -1;
}