diff --git a/tools/keytools/sign.c b/tools/keytools/sign.c index 7370af46..b23633a7 100644 --- a/tools/keytools/sign.c +++ b/tools/keytools/sign.c @@ -2516,16 +2516,27 @@ static int base_diff(const char *f_base, uint8_t *pubkey, uint32_t pubkey_sz, in if (CMD.cert_chain_file != NULL) { struct stat cc_stat; if ((stat(CMD.cert_chain_file, &cc_stat) == 0) && - (cc_stat.st_size >= 0) && - ((uintmax_t)cc_stat.st_size <= (uintmax_t)UINT32_MAX)) { - uint32_t required_space = header_required_size(1, - (uint32_t)cc_stat.st_size, 0); - if (CMD.header_sz < required_space) { - uint32_t new_size = 256; - while (new_size < required_space) { - new_size *= 2; + (cc_stat.st_size >= 0)) { + if ((uintmax_t)cc_stat.st_size > (uintmax_t)UINT16_MAX) { + printf("Error: Certificate chain too large for TLV encoding " + "(%ju > %u)\n", (uintmax_t)cc_stat.st_size, UINT16_MAX); + goto cleanup; + } + else { + uint32_t required_space = header_required_size(1, + (uint32_t)cc_stat.st_size, 0); + if (CMD.header_sz < required_space) { + uint32_t new_size = 256; + while (new_size < required_space) { + if (new_size > (UINT32_MAX / 2U)) { + printf("Error: Header size overflow while sizing " + "certificate chain\n"); + goto cleanup; + } + new_size *= 2; + } + CMD.header_sz = new_size; } - CMD.header_sz = new_size; } } } diff --git a/tools/squashelf/test-range-overflow.py b/tools/squashelf/test-range-overflow.py index db0747a9..45a6cf18 100644 --- a/tools/squashelf/test-range-overflow.py +++ b/tools/squashelf/test-range-overflow.py @@ -72,29 +72,28 @@ def run(squashelf, infile, outfile, rng): def main(): squashelf = sys.argv[1] if len(sys.argv) > 1 else "./squashelf" - d = tempfile.mkdtemp() rc = 0 + with tempfile.TemporaryDirectory() as d: + # 1) Overflow segment: p_paddr + p_memsz - 1 wraps below p_paddr, so the + # wrapped end (~0x4fe) is inside [0, 0x1000] even though the real span + # covers the whole address space. It MUST be excluded (non-zero exit, + # no output segment). + bad = os.path.join(d, "overflow.elf") + make_elf64(bad, paddr=0x500, memsz=UINT64_MAX) + if run(squashelf, bad, os.path.join(d, "bad.out"), "0x0-0x1000") == 0: + print("FAIL: overflow segment was wrongly included by range filter") + rc = 1 + else: + print("PASS: overflow segment excluded") - # 1) Overflow segment: p_paddr + p_memsz - 1 wraps below p_paddr, so the - # wrapped end (~0x4fe) is inside [0, 0x1000] even though the real span - # covers the whole address space. It MUST be excluded (non-zero exit, - # no output segment). - bad = os.path.join(d, "overflow.elf") - make_elf64(bad, paddr=0x500, memsz=UINT64_MAX) - if run(squashelf, bad, os.path.join(d, "bad.out"), "0x0-0x1000") == 0: - print("FAIL: overflow segment was wrongly included by range filter") - rc = 1 - else: - print("PASS: overflow segment excluded") - - # 2) Regression guard: a normal in-range segment must still be kept. - good = os.path.join(d, "ok.elf") - make_elf64(good, paddr=0x500, memsz=0x100) - if run(squashelf, good, os.path.join(d, "good.out"), "0x0-0x1000") != 0: - print("FAIL: normal in-range segment was dropped") - rc = 1 - else: - print("PASS: normal in-range segment kept") + # 2) Regression guard: a normal in-range segment must still be kept. + good = os.path.join(d, "ok.elf") + make_elf64(good, paddr=0x500, memsz=0x100) + if run(squashelf, good, os.path.join(d, "good.out"), "0x0-0x1000") != 0: + print("FAIL: normal in-range segment was dropped") + rc = 1 + else: + print("PASS: normal in-range segment kept") sys.exit(rc) diff --git a/tools/tpm/rot.c b/tools/tpm/rot.c index 5f8973f7..9de7bce1 100644 --- a/tools/tpm/rot.c +++ b/tools/tpm/rot.c @@ -161,17 +161,20 @@ static int TPM2_Boot_SecureROT_Example(TPMI_RH_NV_AUTH authHandle, word32 nvBase } if (rc == 0) { digestSz = nvPublic.dataSize; + word32 digestReadSz; /* dataSize is supplied by the TPM over the bus; clamp it to the * digest buffer so a malicious/emulated TPM (or a pre-existing NV * index larger than the hash) cannot overflow digest[] during the * read-back below, which uses digestSz as the copy count. */ if (digestSz > (int)sizeof(digest)) digestSz = (int)sizeof(digest); + digestReadSz = (word32)digestSz; /* Read access */ printf("Reading NV 0x%x public key hash\n", nv.handle.hndl); rc = wolfTPM2_NVReadAuth(&dev, &nv, nv.handle.hndl, - digest, (word32*)&digestSz, 0); + digest, &digestReadSz, 0); + digestSz = (int)digestReadSz; } if (rc == 0) { printf("Read Public Key Hash (%d)\n", digestSz); diff --git a/tools/unit-tests/unit-sign-delta-cert-inv-off.py b/tools/unit-tests/unit-sign-delta-cert-inv-off.py index 5f09fd5e..314ce848 100644 --- a/tools/unit-tests/unit-sign-delta-cert-inv-off.py +++ b/tools/unit-tests/unit-sign-delta-cert-inv-off.py @@ -78,6 +78,8 @@ def find_tlv_u32(data, want_type, scan_end): continue length = data[p + 2] | (data[p + 3] << 8) if htype == want_type: + if length != 4 or p + 4 + length > scan_end: + return None return struct.unpack("