summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@chromium.org>2019-11-13 00:07:56 -0500
committerCommit Bot <commit-bot@chromium.org>2019-11-14 23:13:53 +0000
commite1ce1ae39ee02d2b8647a0202e1c3779f5f1f7bc (patch)
tree2b57286c1fee99287c81a59420fb9ba418a51dad
parent8c417c9303d9d8db1485c1945fd37f64139923f8 (diff)
downloadvboot-e1ce1ae39ee02d2b8647a0202e1c3779f5f1f7bc.tar.gz
futility: updater: sync mtimes
When unpacking files, unzip will retain timestamps on the outputs. This makes it easy to recreate the firmware unpacker with the same exact contents. futility doesn't copy update timestamps anywhere, so all the mtimes are $now, which makes it impossible to recreate the same archive. Update the API to pass around mtimes by reading them from inputs, setting them on outputs, and copying them across. BUG=None TEST=`futility update -a chromeos-firmwareupdate --unpack out` has timestamps on outputs BRANCH=None Change-Id: Icc0ae833390115082e1677d190d1b2a029b78439 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1913067 Reviewed-by: Hung-Te Lin <hungte@chromium.org> Commit-Queue: Mike Frysinger <vapier@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org> (cherry picked from commit c48a593b26d2353eb8788dd85ba8618555180f55) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1918004 Reviewed-by: Shelley Chen <shchen@chromium.org> Commit-Queue: Shelley Chen <shchen@chromium.org> Tested-by: Shelley Chen <shchen@chromium.org>
-rw-r--r--futility/updater.c4
-rw-r--r--futility/updater.h4
-rw-r--r--futility/updater_archive.c54
3 files changed, 41 insertions, 21 deletions
diff --git a/futility/updater.c b/futility/updater.c
index 25b20a7d..27691404 100644
--- a/futility/updater.c
+++ b/futility/updater.c
@@ -639,8 +639,8 @@ int load_firmware_image(struct firmware_image *image, const char *file_name,
ERROR("Does not exist: %s\n", file_name);
return -1;
}
- if (archive_read_file(archive, file_name, &image->data, &image->size) !=
- VB2_SUCCESS) {
+ if (archive_read_file(archive, file_name, &image->data, &image->size, NULL)
+ != VB2_SUCCESS) {
ERROR("Failed to load %s\n", file_name);
return -1;
}
diff --git a/futility/updater.h b/futility/updater.h
index 51526998..2f5603e2 100644
--- a/futility/updater.h
+++ b/futility/updater.h
@@ -292,7 +292,7 @@ int archive_has_entry(struct archive *ar, const char *name);
* otherwise non-zero as failure.
*/
int archive_read_file(struct archive *ar, const char *fname,
- uint8_t **data, uint32_t *size);
+ uint8_t **data, uint32_t *size, int64_t *mtime);
/*
* Writes a file into archive.
@@ -301,7 +301,7 @@ int archive_read_file(struct archive *ar, const char *fname,
* Returns 0 on success, otherwise non-zero as failure.
*/
int archive_write_file(struct archive *ar, const char *fname,
- uint8_t *data, uint32_t size);
+ uint8_t *data, uint32_t size, int64_t mtime);
/*
* Copies all entries from one archive to another.
diff --git a/futility/updater_archive.c b/futility/updater_archive.c
index da2e99ee..5d8e414d 100644
--- a/futility/updater_archive.c
+++ b/futility/updater_archive.c
@@ -7,11 +7,13 @@
#include <assert.h>
#include <ctype.h>
+#include <errno.h>
#include <fts.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <unistd.h>
#ifdef HAVE_LIBZIP
@@ -80,9 +82,9 @@ struct archive {
int (*callback)(const char *path, void *arg));
int (*has_entry)(void *handle, const char *name);
int (*read_file)(void *handle, const char *fname,
- uint8_t **data, uint32_t *size);
+ uint8_t **data, uint32_t *size, int64_t *mtime);
int (*write_file)(void *handle, const char *fname,
- uint8_t *data, uint32_t size);
+ uint8_t *data, uint32_t size, int64_t mtime);
};
/*
@@ -164,23 +166,30 @@ static int archive_fallback_has_entry(void *handle, const char *fname)
/* Callback for archive_read_file on a general file system. */
static int archive_fallback_read_file(void *handle, const char *fname,
- uint8_t **data, uint32_t *size)
+ uint8_t **data, uint32_t *size, int64_t *mtime)
{
int r;
char *temp_path = NULL;
const char *path = archive_fallback_get_path(handle, fname, &temp_path);
+ struct stat st;
VB2_DEBUG("Reading %s\n", path);
*data = NULL;
*size = 0;
r = vb2_read_file(path, data, size) != VB2_SUCCESS;
+ if (mtime) {
+ if (stat(path, &st) == 0)
+ *mtime = st.st_mtime;
+ else
+ WARN("Unable to stat %s: %s\n", path, strerror(errno));
+ }
free(temp_path);
return r;
}
/* Callback for archive_write_file on a general file system. */
static int archive_fallback_write_file(void *handle, const char *fname,
- uint8_t *data, uint32_t size)
+ uint8_t *data, uint32_t size, int64_t mtime)
{
int r;
char *temp_path = NULL;
@@ -200,6 +209,14 @@ static int archive_fallback_write_file(void *handle, const char *fname,
free(dirname);
}
r = vb2_write_file(path, data, size) != VB2_SUCCESS;
+ if (mtime) {
+ struct timeval times[2] = {
+ {.tv_sec = mtime, .tv_usec = 0},
+ {.tv_sec = mtime, .tv_usec = 0},
+ };
+ if (utimes(path, times) != 0)
+ WARN("Unable to set times on %s: %s\n", path, strerror(errno));
+ }
free(temp_path);
return r;
}
@@ -254,7 +271,7 @@ static int archive_zip_walk(
/* Callback for archive_zip_read_file on a ZIP file. */
static int archive_zip_read_file(void *handle, const char *fname,
- uint8_t **data, uint32_t *size)
+ uint8_t **data, uint32_t *size, int64_t *mtime)
{
struct zip *zip = (struct zip *)handle;
struct zip_file *fp;
@@ -276,6 +293,8 @@ static int archive_zip_read_file(void *handle, const char *fname,
*data = (uint8_t *)malloc(stat.size);
if (*data) {
if (zip_fread(fp, *data, stat.size) == stat.size) {
+ if (mtime)
+ *mtime = stat.mtime;
*size = stat.size;
} else {
ERROR("Failed to read entry in zip: %s\n", fname);
@@ -289,7 +308,7 @@ static int archive_zip_read_file(void *handle, const char *fname,
/* Callback for archive_zip_write_file on a ZIP file. */
static int archive_zip_write_file(void *handle, const char *fname,
- uint8_t *data, uint32_t size)
+ uint8_t *data, uint32_t size, int64_t mtime)
{
struct zip *zip = (struct zip *)handle;
struct zip_source *src;
@@ -309,7 +328,7 @@ static int archive_zip_write_file(void *handle, const char *fname,
}
/* zip_source_free is not needed if zip_file_add success. */
#if LIBZIP_VERSION_MAJOR >= 1
- zip_file_set_mtime(zip, zip_name_locate(zip, fname, 0), 0, 0);
+ zip_file_set_mtime(zip, zip_name_locate(zip, fname, 0), mtime, 0);
#endif
return 0;
}
@@ -418,11 +437,11 @@ static int archive_walk(struct archive *ar, void *arg,
* otherwise non-zero as failure.
*/
int archive_read_file(struct archive *ar, const char *fname,
- uint8_t **data, uint32_t *size)
+ uint8_t **data, uint32_t *size, int64_t *mtime)
{
if (!ar || *fname == '/')
- return archive_fallback_read_file(NULL, fname, data, size);
- return ar->read_file(ar->handle, fname, data, size);
+ return archive_fallback_read_file(NULL, fname, data, size, mtime);
+ return ar->read_file(ar->handle, fname, data, size, mtime);
}
/*
@@ -432,11 +451,11 @@ int archive_read_file(struct archive *ar, const char *fname,
* Returns 0 on success, otherwise non-zero as failure.
*/
int archive_write_file(struct archive *ar, const char *fname,
- uint8_t *data, uint32_t size)
+ uint8_t *data, uint32_t size, int64_t mtime)
{
if (!ar || *fname == '/')
- return archive_fallback_write_file(NULL, fname, data, size);
- return ar->write_file(ar->handle, fname, data, size);
+ return archive_fallback_write_file(NULL, fname, data, size, mtime);
+ return ar->write_file(ar->handle, fname, data, size, mtime);
}
struct _copy_arg {
@@ -449,14 +468,15 @@ static int archive_copy_callback(const char *path, void *_arg)
const struct _copy_arg *arg = (const struct _copy_arg*)_arg;
uint32_t size;
uint8_t *data;
+ int64_t mtime;
int r;
INFO("Copying: %s\n", path);
- if (archive_read_file(arg->from, path, &data, &size)) {
+ if (archive_read_file(arg->from, path, &data, &size, &mtime)) {
ERROR("Failed reading: %s\n", path);
return 1;
}
- r = archive_write_file(arg->to, path, data, size);
+ r = archive_write_file(arg->to, path, data, size, mtime);
VB2_DEBUG("result=%d\n", r);
free(data);
return r;
@@ -536,7 +556,7 @@ static int model_config_parse_setvars_file(
char *line, *k, *v;
int valid = 0;
- if (archive_read_file(archive, fpath, &data, &len) != 0) {
+ if (archive_read_file(archive, fpath, &data, &len, NULL) != 0) {
ERROR("Failed reading: %s\n", fpath);
return -1;
}
@@ -648,7 +668,7 @@ static int apply_key_file(
uint8_t *data = NULL;
uint32_t len;
- r = archive_read_file(archive, path, &data, &len);
+ r = archive_read_file(archive, path, &data, &len, NULL);
if (r == 0) {
VB2_DEBUG("Loaded file: %s\n", path);
r = apply(image, section_name, data, len);