]> git.ipfire.org Git - thirdparty/git.git/commitdiff
treewide: fix various bugs w/ OpenSSL 3+ EVP API
authorEric Wong <e@80x24.org>
Fri, 1 Sep 2023 02:09:28 +0000 (02:09 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 1 Sep 2023 05:26:01 +0000 (22:26 -0700)
The OpenSSL 3+ EVP API for SHA-* cannot support our prior use cases
supported by other SHA-* implementations.  It has the following
differences:

1. ->init_fn is required before all use
2. struct assignments don't work and requires ->clone_fn
3. can't support ->update_fn after ->final_*fn

While fixing cases 1 and 2 is merely the matter of calling ->init_fn and
->clone_fn as appropriate, fixing case 3 requires calling ->final_*fn on
a temporary context that's cloned from the primary context.

Reported-by: Bagas Sanjaya <bagasdotme@gmail.com>
Link: https://lore.kernel.org/ZPCL11k38PXTkFga@debian.me/
Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Fixes: 3e440ea0aba0 ("sha256: avoid functions deprecated in OpenSSL 3+")
Fixes: bda9c12073e7 ("avoid SHA-1 functions deprecated in OpenSSL 3+")
Signed-off-by: Eric Wong <e@80x24.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/fast-import.c
builtin/index-pack.c
builtin/unpack-objects.c
bulk-checkin.c
csum-file.c

index bbd9b2b3e715db7e84011cc41542e2fe6dd4d4f0..09751422eb5d90050ca9d77e94fb7a4c1c7f5c7a 100644 (file)
@@ -1103,6 +1103,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
                || (pack_size + PACK_SIZE_THRESHOLD + len) < pack_size)
                cycle_packfile();
 
+       the_hash_algo->init_fn(&checkpoint.ctx);
        hashfile_checkpoint(pack_file, &checkpoint);
        offset = checkpoint.offset;
 
index bb67e16655994ceee8116a6325ead1daf1d8e860..81194c9f27e878447907bb1f680f59c9ee6d5fd1 100644 (file)
@@ -1166,6 +1166,7 @@ static void parse_pack_objects(unsigned char *hash)
        struct ofs_delta_entry *ofs_delta = ofs_deltas;
        struct object_id ref_delta_oid;
        struct stat st;
+       git_hash_ctx tmp_ctx;
 
        if (verbose)
                progress = start_progress(
@@ -1202,7 +1203,9 @@ static void parse_pack_objects(unsigned char *hash)
 
        /* Check pack integrity */
        flush();
-       the_hash_algo->final_fn(hash, &input_ctx);
+       the_hash_algo->init_fn(&tmp_ctx);
+       the_hash_algo->clone_fn(&tmp_ctx, &input_ctx);
+       the_hash_algo->final_fn(hash, &tmp_ctx);
        if (!hasheq(fill(the_hash_algo->rawsz), hash))
                die(_("pack is corrupted (SHA1 mismatch)"));
        use(the_hash_algo->rawsz);
index 2c52c3a741fbd49d7782f6388e2ebe38f54cb8fb..b16d38af13300eff203a3f57e108b5886dade618 100644 (file)
@@ -608,6 +608,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
 {
        int i;
        struct object_id oid;
+       git_hash_ctx tmp_ctx;
 
        read_replace_refs = 0;
 
@@ -668,7 +669,9 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
        the_hash_algo->init_fn(&ctx);
        unpack_all();
        the_hash_algo->update_fn(&ctx, buffer, offset);
-       the_hash_algo->final_oid_fn(&oid, &ctx);
+       the_hash_algo->init_fn(&tmp_ctx);
+       the_hash_algo->clone_fn(&tmp_ctx, &ctx);
+       the_hash_algo->final_oid_fn(&oid, &tmp_ctx);
        if (strict) {
                write_rest();
                if (fsck_finish(&fsck_options))
index d843279715c3369ed92f853bd91c0e846af55049..d03a40f2f9a0fe5000fc06ce667d9fc24e7635be 100644 (file)
@@ -270,6 +270,7 @@ static int deflate_to_pack(struct bulk_checkin_packfile *state,
                                          type, size);
        the_hash_algo->init_fn(&ctx);
        the_hash_algo->update_fn(&ctx, obuf, header_len);
+       the_hash_algo->init_fn(&checkpoint.ctx);
 
        /* Note: idx is non-NULL when we are writing */
        if ((flags & HASH_WRITE_OBJECT) != 0)
index daf9b06dfff60efb47a603c4e8aa410848933e56..87961252c2c19301555cf138fced7ba98d79cbbf 100644 (file)
@@ -208,7 +208,7 @@ int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint
            lseek(f->fd, offset, SEEK_SET) != offset)
                return -1;
        f->total = offset;
-       f->ctx = checkpoint->ctx;
+       the_hash_algo->clone_fn(&f->ctx, &checkpoint->ctx);
        f->offset = 0; /* hashflush() was called in checkpoint */
        return 0;
 }