From: Lennart Poettering Date: Fri, 7 Nov 2025 12:52:38 +0000 (+0100) Subject: pull-job: port .payload field to struct iovec X-Git-Tag: v259-rc1~127^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=729e1f24c55b6bc6cfa1042cfbbaa36e48d7f40f;p=thirdparty%2Fsystemd.git pull-job: port .payload field to struct iovec struct iovec is really how we should encode any form of arbitrary blob data --- diff --git a/src/import/pull-common.c b/src/import/pull-common.c index a58b8b8185f..12d9736725c 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -380,8 +380,8 @@ static int verify_one(PullJob *checksum_job, PullJob *job) { if (!line) return log_oom(); - p = memmem_safe(checksum_job->payload, - checksum_job->payload_size, + p = memmem_safe(checksum_job->payload.iov_base, + checksum_job->payload.iov_len, line, strlen(line)); if (p) @@ -389,7 +389,7 @@ static int verify_one(PullJob *checksum_job, PullJob *job) { } /* Only counts if found at beginning of a line */ - if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) + if (!p || (p != (char*) checksum_job->payload.iov_base && p[-1] != '\n')) return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "DOWNLOAD INVALID: Checksum of %s file did not check out, file has been tampered with.", fn); @@ -398,8 +398,8 @@ static int verify_one(PullJob *checksum_job, PullJob *job) { } static int verify_gpg( - const void *payload, size_t payload_size, - const void *signature, size_t signature_size) { + const struct iovec *payload, + const struct iovec *signature) { _cleanup_close_pair_ int gpg_pipe[2] = EBADF_PAIR; _cleanup_(rm_rf_physical_and_freep) char *gpg_home = NULL; @@ -407,21 +407,21 @@ static int verify_gpg( _cleanup_(sigkill_waitp) pid_t pid = 0; int r; - assert(payload || payload_size == 0); - assert(signature || signature_size == 0); + assert(iovec_is_valid(payload)); + assert(iovec_is_valid(signature)); r = pipe2(gpg_pipe, O_CLOEXEC); if (r < 0) return log_error_errno(errno, "Failed to create pipe for gpg: %m"); - if (signature_size > 0) { + if (iovec_is_set(signature)) { _cleanup_close_ int sig_file = -EBADF; sig_file = mkostemp(sig_file_path, O_RDWR); if (sig_file < 0) return log_error_errno(errno, "Failed to create temporary file: %m"); - r = loop_write(sig_file, signature, signature_size); + r = loop_write(sig_file, signature->iov_base, signature->iov_len); if (r < 0) { log_error_errno(r, "Failed to write to temporary file: %m"); goto finish; @@ -487,10 +487,12 @@ static int verify_gpg( gpg_pipe[0] = safe_close(gpg_pipe[0]); - r = loop_write(gpg_pipe[1], payload, payload_size); - if (r < 0) { - log_error_errno(r, "Failed to write to pipe: %m"); - goto finish; + if (iovec_is_set(payload)) { + r = loop_write(gpg_pipe[1], payload->iov_base, payload->iov_len); + if (r < 0) { + log_error_errno(r, "Failed to write to pipe: %m"); + goto finish; + } } gpg_pipe[1] = safe_close(gpg_pipe[1]); @@ -507,7 +509,7 @@ static int verify_gpg( } finish: - if (signature_size > 0) + if (iovec_is_set(signature)) (void) unlink(sig_file_path); return r; @@ -553,7 +555,7 @@ int pull_verify(ImportVerify verify, assert(checksum_job); assert(checksum_job->state == PULL_JOB_DONE); - if (!checksum_job->payload || checksum_job->payload_size <= 0) + if (!iovec_is_set(&checksum_job->payload)) return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Checksum is empty, cannot verify."); @@ -579,11 +581,11 @@ int pull_verify(ImportVerify verify, assert(signature_job); assert(signature_job->state == PULL_JOB_DONE); - if (!signature_job->payload || signature_job->payload_size <= 0) + if (!iovec_is_set(&signature_job->payload)) return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Signature is empty, cannot verify."); - return verify_gpg(verify_job->payload, verify_job->payload_size, signature_job->payload, signature_job->payload_size); + return verify_gpg(&verify_job->payload, &signature_job->payload); } int verification_style_from_url(const char *url, VerificationStyle *ret) { diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 1945106099d..621a90a86e3 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -57,7 +57,7 @@ PullJob* pull_job_unref(PullJob *j) { free(j->url); free(j->etag); strv_free(j->old_etags); - free(j->payload); + iovec_done(&j->payload); iovec_done(&j->checksum); iovec_done(&j->expected_checksum); @@ -95,8 +95,7 @@ static int pull_job_restart(PullJob *j, const char *new_url) { j->state = PULL_JOB_INIT; j->error = 0; - j->payload = mfree(j->payload); - j->payload_size = 0; + iovec_done(&j->payload); j->written_compressed = 0; j->written_uncompressed = 0; j->content_length = UINT64_MAX; @@ -381,11 +380,14 @@ static int pull_job_write_uncompressed(const void *p, size_t sz, void *userdata) } if (j->disk_fd < 0 || j->force_memory) { - if (!GREEDY_REALLOC(j->payload, j->payload_size + sz + 1)) + uint8_t *a = j->payload.iov_base; + + if (!GREEDY_REALLOC(a, j->payload.iov_len + sz + 1)) return log_oom(); - *((char*) mempcpy(j->payload + j->payload_size, p, sz)) = 0; - j->payload_size += sz; + *((uint8_t*) mempcpy(a + j->payload.iov_len, p, sz)) = 0; + j->payload.iov_base = a; + j->payload.iov_len += sz; } j->written_uncompressed += sz; @@ -397,39 +399,39 @@ finish: return 0; } -static int pull_job_write_compressed(PullJob *j, void *p, size_t sz) { +static int pull_job_write_compressed(PullJob *j, const struct iovec *data) { int r; assert(j); - assert(p); + assert(iovec_is_valid(data)); - if (sz <= 0) + if (!iovec_is_set(data)) return 0; - if (j->written_compressed + sz < j->written_compressed) + if (j->written_compressed + data->iov_len < j->written_compressed) return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "File too large, overflow"); - if (j->written_compressed + sz > j->compressed_max) + if (j->written_compressed + data->iov_len > j->compressed_max) return log_error_errno(SYNTHETIC_ERRNO(EFBIG), "File overly large, refusing."); uint64_t cl = pull_job_content_length_effective(j); if (cl != UINT64_MAX && - j->written_compressed + sz > cl) + j->written_compressed + data->iov_len > cl) return log_error_errno(SYNTHETIC_ERRNO(EFBIG), "Content length incorrect."); if (j->checksum_ctx) { - r = EVP_DigestUpdate(j->checksum_ctx, p, sz); + r = EVP_DigestUpdate(j->checksum_ctx, data->iov_base, data->iov_len); if (r == 0) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Could not hash chunk."); } - r = import_uncompress(&j->compress, p, sz, pull_job_write_uncompressed, j); + r = import_uncompress(&j->compress, data->iov_base, data->iov_len, pull_job_write_uncompressed, j); if (r < 0) return r; - j->written_compressed += sz; + j->written_compressed += data->iov_len; return 0; } @@ -470,14 +472,11 @@ static int pull_job_open_disk(PullJob *j) { } static int pull_job_detect_compression(PullJob *j) { - _cleanup_free_ uint8_t *stub = NULL; - size_t stub_size; - int r; assert(j); - r = import_uncompress_detect(&j->compress, j->payload, j->payload_size); + r = import_uncompress_detect(&j->compress, j->payload.iov_base, j->payload.iov_len); if (r < 0) return log_error_errno(r, "Failed to initialize compressor: %m"); if (r == 0) @@ -490,15 +489,11 @@ static int pull_job_detect_compression(PullJob *j) { return r; /* Now, take the payload we read so far, and decompress it */ - stub = j->payload; - stub_size = j->payload_size; - - j->payload = NULL; - j->payload_size = 0; + _cleanup_(iovec_done) struct iovec stub = TAKE_STRUCT(j->payload); j->state = PULL_JOB_RUNNING; - r = pull_job_write_compressed(j, stub, stub_size); + r = pull_job_write_compressed(j, &stub); if (r < 0) return r; @@ -516,15 +511,11 @@ static size_t pull_job_write_callback(void *contents, size_t size, size_t nmemb, case PULL_JOB_ANALYZING: /* Let's first check what it actually is */ - - if (!GREEDY_REALLOC(j->payload, j->payload_size + sz)) { + if (!iovec_append(&j->payload, &IOVEC_MAKE(contents, sz))) { r = log_oom(); goto fail; } - memcpy(j->payload + j->payload_size, contents, sz); - j->payload_size += sz; - r = pull_job_detect_compression(j); if (r < 0) goto fail; @@ -532,8 +523,7 @@ static size_t pull_job_write_callback(void *contents, size_t size, size_t nmemb, break; case PULL_JOB_RUNNING: - - r = pull_job_write_compressed(j, contents, sz); + r = pull_job_write_compressed(j, &IOVEC_MAKE(contents, sz)); if (r < 0) goto fail; diff --git a/src/import/pull-job.h b/src/import/pull-job.h index 178cb8a30a1..b0742381740 100644 --- a/src/import/pull-job.h +++ b/src/import/pull-job.h @@ -60,8 +60,7 @@ typedef struct PullJob { uint64_t expected_content_length; - uint8_t *payload; - size_t payload_size; + struct iovec payload; int disk_fd; bool close_disk_fd;