diff --git a/src/barebox-state/backend_bucket_circular.c b/src/barebox-state/backend_bucket_circular.c index 8eae866..0b8286f 100644 --- a/src/barebox-state/backend_bucket_circular.c +++ b/src/barebox-state/backend_bucket_circular.c @@ -227,7 +227,7 @@ static int state_backend_bucket_circular_read(struct state_backend_storage_bucket *bucket, uint8_t ** buf_out, - ssize_t * len_hint) + ssize_t * len_out) { struct state_backend_storage_bucket_circular *circ = get_bucket_circular(bucket); @@ -282,7 +282,7 @@ } *buf_out = buf; - *len_hint = read_len - sizeof(struct state_backend_storage_bucket_circular_meta); + *len_out = read_len - sizeof(struct state_backend_storage_bucket_circular_meta); return ret; } diff --git a/src/barebox-state/backend_bucket_direct.c b/src/barebox-state/backend_bucket_direct.c index 5225433..06a5433 100644 --- a/src/barebox-state/backend_bucket_direct.c +++ b/src/barebox-state/backend_bucket_direct.c @@ -47,7 +47,7 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket *bucket, uint8_t ** buf_out, - ssize_t * len_hint) + ssize_t * len_out) { struct state_backend_storage_bucket_direct *direct = get_bucket_direct(bucket); @@ -69,18 +69,13 @@ if (meta.magic == direct_magic) { read_len = meta.written_length; } else { - if (*len_hint) - read_len = *len_hint; - else - read_len = direct->max_size; + read_len = direct->max_size; ret = lseek(direct->fd, direct->offset, SEEK_SET); if (ret < 0) { dev_err(direct->dev, "Failed to seek file, %d\n", ret); return ret; } } - if (direct->max_size) - read_len = min(read_len, direct->max_size); buf = xmalloc(read_len); if (!buf) @@ -94,7 +89,7 @@ } *buf_out = buf; - *len_hint = read_len; + *len_out = read_len; return 0; } diff --git a/src/barebox-state/backend_format_dtb.c b/src/barebox-state/backend_format_dtb.c index dc19c88..abf8921 100644 --- a/src/barebox-state/backend_format_dtb.c +++ b/src/barebox-state/backend_format_dtb.c @@ -40,12 +40,13 @@ static int state_backend_format_dtb_verify(struct state_backend_format *format, uint32_t magic, const uint8_t * buf, - ssize_t len) + ssize_t *lenp) { struct state_backend_format_dtb *fdtb = get_format_dtb(format); struct device_node *root; struct fdt_header *fdt = (struct fdt_header *)buf; size_t dtb_len = fdt32_to_cpu(fdt->totalsize); + size_t len = *lenp; if (dtb_len > len) { dev_err(fdtb->dev, "Error, stored DTB length (%d) longer than read buffer (%d)\n", @@ -67,6 +68,8 @@ fdtb->root = root; + *lenp = be32_to_cpu(fdt->totalsize); + return 0; } @@ -78,7 +81,7 @@ int ret; if (!fdtb->root) { - state_backend_format_dtb_verify(format, 0, buf, len); + state_backend_format_dtb_verify(format, 0, buf, &len); } ret = state_from_node(state, fdtb->root, 0); diff --git a/src/barebox-state/backend_format_raw.c b/src/barebox-state/backend_format_raw.c index e028ea6..3c8956f 100644 --- a/src/barebox-state/backend_format_raw.c +++ b/src/barebox-state/backend_format_raw.c @@ -55,13 +55,14 @@ static int backend_format_raw_verify(struct state_backend_format *format, uint32_t magic, const uint8_t * buf, - ssize_t len) + ssize_t *lenp) { uint32_t crc; struct backend_raw_header *header; int d_len = 0; int ret; const uint8_t *data; + ssize_t len = *lenp; struct state_backend_format_raw *backend_raw = get_format_raw(format); ssize_t complete_len; @@ -105,6 +106,8 @@ return -EINVAL; } + *lenp = header->data_len + sizeof(*header); + if (backend_raw->digest) { struct digest *d = backend_raw->digest; const void *hmac = data + header->data_len; diff --git a/src/barebox-state/backend_storage.c b/src/barebox-state/backend_storage.c index c6a3e44..ef40a8f 100644 --- a/src/barebox-state/backend_storage.c +++ b/src/barebox-state/backend_storage.c @@ -112,15 +112,18 @@ int ret; list_for_each_entry(bucket, &storage->buckets, bucket_list) { - *len = 0; - ret = bucket->read(bucket, buf, len); if (ret) { dev_warn(storage->dev, "Failed to read from state backend bucket, trying next, %d\n", ret); continue; } - ret = format->verify(format, magic, *buf, *len); + + /* + * Verify the buffer crcs. The buffer length is passed in the len argument, + * .verify overwrites it with the length actually used. + */ + ret = format->verify(format, magic, *buf, len); if (!ret) { goto found; } diff --git a/src/barebox-state/state.h b/src/barebox-state/state.h index 6f5de31..0b1a7e5 100644 --- a/src/barebox-state/state.h +++ b/src/barebox-state/state.h @@ -46,7 +46,7 @@ */ struct state_backend_format { int (*verify) (struct state_backend_format * format, uint32_t magic, - const uint8_t * buf, ssize_t len); + const uint8_t * buf, ssize_t *lenp); int (*pack) (struct state_backend_format * format, struct state * state, uint8_t ** buf, ssize_t * len); int (*unpack) (struct state_backend_format * format,