From be7c98c24072448a5ea7645c20ee94f03acb2da0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Jan 2021 22:32:21 +0100 Subject: [PATCH 1/5] import: fix typo in help text --- src/import/pull.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/import/pull.c b/src/import/pull.c index 33e6196f79..a54f968cd7 100644 --- a/src/import/pull.c +++ b/src/import/pull.c @@ -212,7 +212,8 @@ static int help(int argc, char *argv[], void *userdata) { " 'checksum', 'signature'\n" " --settings=BOOL Download settings file with image\n" " --roothash=BOOL Download root hash file with image\n" - " --roothash-sigature=BOOL Download root hash signature file with image\n" + " --roothash-signature=BOOL\n" + " Download root hash signature file with image\n" " --verity=BOOL Download verity file with image\n" " --image-root=PATH Image root directory\n\n" "Commands:\n" From 0dfb650387c2ca578b25c7239995141528236b99 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Jan 2021 16:02:13 +0100 Subject: [PATCH 2/5] import: use unlink_and_free() + rm_rf_subvolume_and_free() more --- src/import/import-raw.c | 5 +---- src/import/import-tar.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/import/import-raw.c b/src/import/import-raw.c index f6ee86d625..3b7031daf6 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -64,10 +64,7 @@ RawImport* raw_import_unref(RawImport *i) { sd_event_unref(i->event); - if (i->temp_path) { - (void) unlink(i->temp_path); - free(i->temp_path); - } + unlink_and_free(i->temp_path); import_compress_free(&i->compress); diff --git a/src/import/import-tar.c b/src/import/import-tar.c index 6baa2f43ab..c772493ece 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -73,10 +73,7 @@ TarImport* tar_import_unref(TarImport *i) { (void) wait_for_terminate(i->tar_pid, NULL); } - if (i->temp_path) { - (void) rm_rf(i->temp_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME); - free(i->temp_path); - } + rm_rf_subvolume_and_free(i->temp_path); import_compress_free(&i->compress); From 9f0b5640bd316cc23234370abd3a8b2db6e709dd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Jan 2021 18:16:01 +0100 Subject: [PATCH 3/5] import: don't invoke compress callbacks with empty data It's pointless if no data was generated. (This happens if an empty file is compressed) --- src/import/import-compress.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/import/import-compress.c b/src/import/import-compress.c index b89ffb1b2a..c016587e14 100644 --- a/src/import/import-compress.c +++ b/src/import/import-compress.c @@ -125,9 +125,11 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo if (!IN_SET(lzr, LZMA_OK, LZMA_STREAM_END)) return -EIO; - r = callback(buffer, sizeof(buffer) - c->xz.avail_out, userdata); - if (r < 0) - return r; + if (c->xz.avail_out < sizeof(buffer)) { + r = callback(buffer, sizeof(buffer) - c->xz.avail_out, userdata); + if (r < 0) + return r; + } } break; @@ -146,9 +148,11 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo if (!IN_SET(r, Z_OK, Z_STREAM_END)) return -EIO; - r = callback(buffer, sizeof(buffer) - c->gzip.avail_out, userdata); - if (r < 0) - return r; + if (c->gzip.avail_out < sizeof(buffer)) { + r = callback(buffer, sizeof(buffer) - c->gzip.avail_out, userdata); + if (r < 0) + return r; + } } break; @@ -168,9 +172,11 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo if (!IN_SET(r, BZ_OK, BZ_STREAM_END)) return -EIO; - r = callback(buffer, sizeof(buffer) - c->bzip2.avail_out, userdata); - if (r < 0) - return r; + if (c->bzip2.avail_out < sizeof(buffer)) { + r = callback(buffer, sizeof(buffer) - c->bzip2.avail_out, userdata); + if (r < 0) + return r; + } } break; From c9b6ebef8c4ed28edc930bcb77906cee74c0cb34 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Jan 2021 18:20:11 +0100 Subject: [PATCH 4/5] import: make sure we can import empty files --- src/import/import-compress.c | 7 +++++++ src/import/import-compress.h | 1 + src/import/import-raw.c | 40 ++++++++++++++++++------------------ src/import/import-tar.c | 33 ++++++++++++++--------------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/import/import-compress.c b/src/import/import-compress.c index c016587e14..aa837af565 100644 --- a/src/import/import-compress.c +++ b/src/import/import-compress.c @@ -83,6 +83,13 @@ int import_uncompress_detect(ImportCompress *c, const void *data, size_t size) { return 1; } +void import_uncompress_force_off(ImportCompress *c) { + assert(c); + + c->type = IMPORT_COMPRESS_UNCOMPRESSED; + c->encoding = false; +} + int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCompressCallback callback, void *userdata) { int r; diff --git a/src/import/import-compress.h b/src/import/import-compress.h index e40f4dba0a..3c35b59104 100644 --- a/src/import/import-compress.h +++ b/src/import/import-compress.h @@ -37,6 +37,7 @@ typedef int (*ImportCompressCallback)(const void *data, size_t size, void *userd void import_compress_free(ImportCompress *c); int import_uncompress_detect(ImportCompress *c, const void *data, size_t size); +void import_uncompress_force_off(ImportCompress *c); int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCompressCallback callback, void *userdata); int import_compress_init(ImportCompress *c, ImportCompressType t); diff --git a/src/import/import-raw.c b/src/import/import-raw.c index 3b7031daf6..4eb59fbb25 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -313,27 +313,23 @@ static int raw_import_process(RawImport *i) { r = log_error_errno(errno, "Failed to read input file: %m"); goto finish; } - if (l == 0) { - if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { - log_error("Premature end of file."); - r = -EIO; - goto finish; - } - - r = raw_import_finish(i); - goto finish; - } i->buffer_size += l; if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { - r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size); - if (r < 0) { - log_error_errno(r, "Failed to detect file compression: %m"); - goto finish; + + if (l == 0) { /* EOF */ + log_debug("File too short to be compressed, as no compression signature fits in, thus assuming uncompressed."); + import_uncompress_force_off(&i->compress); + } else { + r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size); + if (r < 0) { + log_error_errno(r, "Failed to detect file compression: %m"); + goto finish; + } + if (r == 0) /* Need more data */ + return 0; } - if (r == 0) /* Need more data */ - return 0; r = raw_import_open_disk(i); if (r < 0) @@ -342,10 +338,8 @@ static int raw_import_process(RawImport *i) { r = raw_import_try_reflink(i); if (r < 0) goto finish; - if (r > 0) { - r = raw_import_finish(i); - goto finish; - } + if (r > 0) + goto complete; } r = import_uncompress(&i->compress, i->buffer, i->buffer_size, raw_import_write, i); @@ -357,10 +351,16 @@ static int raw_import_process(RawImport *i) { i->written_compressed += i->buffer_size; i->buffer_size = 0; + if (l == 0) /* EOF */ + goto complete; + raw_import_report_progress(i); return 0; +complete: + r = raw_import_finish(i); + finish: if (i->on_finished) i->on_finished(i, r, i->userdata); diff --git a/src/import/import-tar.c b/src/import/import-tar.c index c772493ece..e94474389d 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -259,27 +259,23 @@ static int tar_import_process(TarImport *i) { r = log_error_errno(errno, "Failed to read input file: %m"); goto finish; } - if (l == 0) { - if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { - log_error("Premature end of file."); - r = -EIO; - goto finish; - } - - r = tar_import_finish(i); - goto finish; - } i->buffer_size += l; if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { - r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size); - if (r < 0) { - log_error_errno(r, "Failed to detect file compression: %m"); - goto finish; + + if (l == 0) { /* EOF */ + log_debug("File too short to be compressed, as no compression signature fits in, thus assuming uncompressed."); + import_uncompress_force_off(&i->compress); + } else { + r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size); + if (r < 0) { + log_error_errno(r, "Failed to detect file compression: %m"); + goto finish; + } + if (r == 0) /* Need more data */ + return 0; } - if (r == 0) /* Need more data */ - return 0; r = tar_import_fork_tar(i); if (r < 0) @@ -295,6 +291,11 @@ static int tar_import_process(TarImport *i) { i->written_compressed += i->buffer_size; i->buffer_size = 0; + if (l == 0) { /* EOF */ + r = tar_import_finish(i); + goto finish; + } + tar_import_report_progress(i); return 0; From ff2f7797587e6b0a4b6ef86a7d0bfdb08a5c3ffe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Jan 2021 16:24:14 +0100 Subject: [PATCH 5/5] import: properly verify roothash_signature + verity download, too Follow-up for 133b34f69a72dc90d4e336837d699245390c9f50 where this was forgotten. While we are at it, bring the parameters into the same order as we declare them in the PullRaw/PullTar objects, i.e. match them to the canonical order. --- src/import/pull-common.c | 25 +++++++++++-------------- src/import/pull-common.h | 2 +- src/import/pull-raw.c | 9 ++++++++- src/import/pull-tar.c | 9 ++++++++- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/import/pull-common.c b/src/import/pull-common.c index 403a0952bc..75c5c7493e 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -490,12 +490,15 @@ finish: int pull_verify(ImportVerify verify, PullJob *main_job, - PullJob *roothash_job, - PullJob *settings_job, PullJob *checksum_job, - PullJob *signature_job) { + PullJob *signature_job, + PullJob *settings_job, + PullJob *roothash_job, + PullJob *roothash_signature_job, + PullJob *verity_job) { VerificationStyle style; + PullJob *j; int r; assert(main_job); @@ -513,17 +516,11 @@ int pull_verify(ImportVerify verify, return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Checksum is empty, cannot verify."); - r = verify_one(checksum_job, main_job); - if (r < 0) - return r; - - r = verify_one(checksum_job, roothash_job); - if (r < 0) - return r; - - r = verify_one(checksum_job, settings_job); - if (r < 0) - return r; + FOREACH_POINTER(j, main_job, settings_job, roothash_job, roothash_signature_job, verity_job) { + r = verify_one(checksum_job, j); + if (r < 0) + return r; + } if (verify == IMPORT_VERIFY_CHECKSUM) return 0; diff --git a/src/import/pull-common.h b/src/import/pull-common.h index acbbab7eab..d420025fab 100644 --- a/src/import/pull-common.h +++ b/src/import/pull-common.h @@ -27,7 +27,7 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co int pull_make_auxiliary_job(PullJob **ret, const char *url, int (*strip_suffixes)(const char *name, char **ret), const char *suffix, CurlGlue *glue, PullJobFinished on_finished, void *userdata); int pull_make_verification_jobs(PullJob **ret_checksum_job, PullJob **ret_signature_job, ImportVerify verify, const char *url, CurlGlue *glue, PullJobFinished on_finished, void *userdata); -int pull_verify(ImportVerify verify, PullJob *main_job, PullJob *roothash_job, PullJob *settings_job, PullJob *checksum_job, PullJob *signature_job); +int pull_verify(ImportVerify verify, PullJob *main_job, PullJob *checksum_job, PullJob *signature_job, PullJob *settings_job, PullJob *roothash_job, PullJob *roothash_signature_job, PullJob *verity_job); typedef enum VerificationStyle { VERIFICATION_PER_FILE, /* SuSE-style ".sha256" files with inline gpg signature */ diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c index 0985dddef3..c9bda3c3b4 100644 --- a/src/import/pull-raw.c +++ b/src/import/pull-raw.c @@ -542,7 +542,14 @@ static void raw_pull_job_on_finished(PullJob *j) { raw_pull_report_progress(i, RAW_VERIFYING); - r = pull_verify(i->verify, i->raw_job, i->roothash_job, i->settings_job, i->checksum_job, i->signature_job); + r = pull_verify(i->verify, + i->raw_job, + i->checksum_job, + i->signature_job, + i->settings_job, + i->roothash_job, + i->roothash_signature_job, + i->verity_job); if (r < 0) goto finish; diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c index 90f439f998..a2ba56df2f 100644 --- a/src/import/pull-tar.c +++ b/src/import/pull-tar.c @@ -336,7 +336,14 @@ static void tar_pull_job_on_finished(PullJob *j) { tar_pull_report_progress(i, TAR_VERIFYING); - r = pull_verify(i->verify, i->tar_job, NULL, i->settings_job, i->checksum_job, i->signature_job); + r = pull_verify(i->verify, + i->tar_job, + i->checksum_job, + i->signature_job, + i->settings_job, + /* roothash_job = */ NULL, + /* roothash_signature_job = */ NULL, + /* verity_job = */ NULL); if (r < 0) goto finish;