diff --git a/gpg-interface.c b/gpg-interface.c index 95abf1ef4e1a0c..60c315fba9732a 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -133,20 +133,20 @@ static struct gpg_format *get_format_by_name(const char *str) return NULL; } -static struct gpg_format *get_format_by_sig(const char *sig) +static struct gpg_format *get_format_by_sig(const char *sig, size_t len) { int j; for (size_t i = 0; i < ARRAY_SIZE(gpg_format); i++) for (j = 0; gpg_format[i].sigs[j]; j++) - if (starts_with(sig, gpg_format[i].sigs[j])) + if (starts_with_mem(sig, len, gpg_format[i].sigs[j])) return gpg_format + i; return NULL; } const char *get_signature_format(const char *buf) { - struct gpg_format *format = get_format_by_sig(buf); + struct gpg_format *format = get_format_by_sig(buf, strlen(buf)); return format ? format->name : "unknown"; } @@ -669,7 +669,7 @@ int check_signature(struct signature_check *sigc, sigc->result = 'N'; sigc->trust_level = TRUST_UNDEFINED; - fmt = get_format_by_sig(signature); + fmt = get_format_by_sig(signature, slen); if (!fmt) die(_("bad/incompatible signature '%s'"), signature); @@ -706,7 +706,7 @@ size_t parse_signed_buffer(const char *buf, size_t size) while (len < size) { const char *eol; - if (get_format_by_sig(buf + len)) + if (get_format_by_sig(buf + len, size - len)) match = len; eol = memchr(buf + len, '\n', size - len); diff --git a/midx.c b/midx.c index 6d1c548e3dae8e..6968fc1c005085 100644 --- a/midx.c +++ b/midx.c @@ -583,10 +583,16 @@ off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos) uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos) { + uint32_t pack_int_id; + pos = midx_for_object(&m, pos); + pack_int_id = get_be32(m->chunk_object_offsets + + (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH); + if (pack_int_id >= m->num_packs) + die(_("bad pack-int-id: %"PRIu32" (%"PRIu32" total packs)"), + pack_int_id, m->num_packs); - return m->num_packs_in_base + get_be32(m->chunk_object_offsets + - (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH); + return m->num_packs_in_base + pack_int_id; } enum midx_fill_result midx_fill_entry(struct multi_pack_index *m, @@ -606,7 +612,7 @@ enum midx_fill_result midx_fill_entry(struct multi_pack_index *m, if (prepare_midx_pack(m, pack_int_id)) return MIDX_FILL_OWNER_UNAVAILABLE; - p = m->packs[pack_int_id - m->num_packs_in_base]; + p = nth_midxed_pack(m, pack_int_id); /* * We are about to tell the caller where they can locate the diff --git a/oss-fuzz/fuzz-reftable.c b/oss-fuzz/fuzz-reftable.c index c46eac2c6bce62..75b8ad0c3d9aef 100644 --- a/oss-fuzz/fuzz-reftable.c +++ b/oss-fuzz/fuzz-reftable.c @@ -33,10 +33,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) struct reftable_ref_record ref = { 0 }; struct reftable_iterator it = { 0 }; - reftable_table_init_ref_iterator(table, &it); - if (!reftable_iterator_seek_ref(&it, "")) - while (!reftable_iterator_next_ref(&it, &ref)) - ; + if (!reftable_table_init_ref_iterator(table, &it)) { + if (!reftable_iterator_seek_ref(&it, "")) + while (!reftable_iterator_next_ref(&it, &ref)) + ; + } reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); @@ -46,10 +47,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) struct reftable_log_record log = { 0 }; struct reftable_iterator it = { 0 }; - reftable_table_init_log_iterator(table, &it); - if (!reftable_iterator_seek_log(&it, "")) - while (!reftable_iterator_next_log(&it, &log)) - ; + if (!reftable_table_init_log_iterator(table, &it)) { + if (!reftable_iterator_seek_log(&it, "")) + while (!reftable_iterator_next_log(&it, &log)) + ; + } reftable_log_record_release(&log); reftable_iterator_destroy(&it); diff --git a/rerere.c b/rerere.c index 1c3745d9e3279a..45bbe6ab2c5439 100644 --- a/rerere.c +++ b/rerere.c @@ -476,8 +476,11 @@ static int handle_file(struct index_state *istate, unlink_or_warn(output); return error(_("could not parse conflict hunks in '%s'"), path); } - if (io.io.wrerror) + if (io.io.wrerror) { + if (output) + unlink_or_warn(output); return -1; + } return has_conflicts; } @@ -729,8 +732,25 @@ static void do_rerere_one_path(struct index_state *istate, /* Has the user resolved it already? */ if (variant >= 0) { - if (!handle_file(istate, path, NULL, NULL)) { - copy_file(the_repository, rerere_path(&buf, id, "postimage"), path, 0666); + int ret = handle_file(istate, path, NULL, NULL); + + if (ret < 0) + goto out; + if (!ret) { + const int had_postimage = + id->collection->status[variant] & RR_HAS_POSTIMAGE; + const char *postimage = + rerere_path(&buf, id, "postimage"); + + if (copy_file(the_repository, + postimage, + path, 0666)) { + if (!had_postimage) + unlink_or_warn(postimage); + error_errno(_("could not copy resolution for '%s'"), + path); + goto out; + } id->collection->status[variant] |= RR_HAS_POSTIMAGE; fprintf_ln(stderr, _("Recorded resolution for '%s'."), path); free_rerere_id(rr_item); @@ -778,7 +798,9 @@ static void do_rerere_one_path(struct index_state *istate, assign_variant(id); variant = id->variant; - handle_file(istate, path, NULL, rerere_path(&buf, id, "preimage")); + if (handle_file(istate, path, NULL, + rerere_path(&buf, id, "preimage")) < 0) + goto out; if (id->collection->status[variant] & RR_HAS_POSTIMAGE) { const char *path = rerere_path(&buf, id, "postimage"); if (unlink(path)) diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index 83b07c6236b167..412089563f5a7c 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -90,7 +90,11 @@ static int read_midx_file(const char *object_dir, const char *checksum, for (i = 0; i < m->num_objects; i++) { nth_midxed_object_oid(&oid, m, i + m->num_objects_in_base); - midx_fill_entry(m, &oid, &e, NULL); + if (midx_fill_entry(m, &oid, &e, NULL) != + MIDX_FILL_HIT) { + ret = error(_("failed to load pack entry")); + goto out; + } printf("%s %"PRIu64"\t%s\n", oid_to_hex(&oid), e.offset, e.p->pack_name); diff --git a/t/unit-tests/u-reftable-table.c b/t/unit-tests/u-reftable-table.c index bd04b477a3eff9..1e4378b2eb1b1d 100644 --- a/t/unit-tests/u-reftable-table.c +++ b/t/unit-tests/u-reftable-table.c @@ -257,7 +257,7 @@ void test_reftable_table__seek_invalid_log_offset(void) * know that the table is corrupt, so the seek must report a format * error instead of pretending that the section is empty. */ - reftable_table_init_log_iterator(table, &it); + cl_assert_equal_i(reftable_table_init_log_iterator(table, &it), 0); cl_assert_equal_i(reftable_iterator_seek_log(&it, ""), REFTABLE_FORMAT_ERROR); diff --git a/wrapper.c b/wrapper.c index 561f9ee9c99fc1..05a9cd369c5971 100644 --- a/wrapper.c +++ b/wrapper.c @@ -376,6 +376,10 @@ ssize_t writev_in_full(int fd, struct iovec *iov, int iovcnt) return -1; } + if (signed_add_overflows(total_written, bytes_written)) { + errno = EOVERFLOW; + return -1; + } total_written += bytes_written; /*