diff --git a/arch/SystemZ/SystemZDisassembler.c b/arch/SystemZ/SystemZDisassembler.c index 359e11be71..448e6cb0bf 100644 --- a/arch/SystemZ/SystemZDisassembler.c +++ b/arch/SystemZ/SystemZDisassembler.c @@ -381,10 +381,16 @@ static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *By Table = DecoderTable16; Inst = readBytes16(MI, Bytes); } else if (Bytes[0] < 0xc0) { + if (BytesLen < 4) { + return MCDisassembler_Fail; + } *Size = 4; Table = DecoderTable32; Inst = readBytes32(MI, Bytes); } else { + if (BytesLen < 6) { + return MCDisassembler_Fail; + } *Size = 6; Table = DecoderTable48; Inst = readBytes48(MI, Bytes); diff --git a/cstool/cstool.c b/cstool/cstool.c index 78312b99d6..3f25ded10c 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -147,13 +147,13 @@ static struct { { "sparcv9", "Sparc v9, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 }, { "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN }, - { "systemz_arch8", "(arch8/z10/generic)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch9", "(arch9/z196)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch10", "(arch10/zec12)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch11", "(arch11/z13)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch12", "(arch12/z14)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch13", "(arch13/z15)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN }, - { "systemz_arch14", "(arch14/z16)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch8", "(arch8/z10/generic)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch9", "(arch9/z196)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch10", "(arch10/zec12)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch11", "(arch11/z13)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch12", "(arch12/z14)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch13", "(arch13/z15)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN }, + { "systemz_arch14", "(arch14/z16)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN }, { "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN }, @@ -637,6 +637,7 @@ int main(int argc, char **argv) address = strtoull(src, &temp, 16); if (temp == src || *temp != '\0' || errno == ERANGE) { fprintf(stderr, "ERROR: invalid address argument, quit!\n"); + free(assembly); return -2; } } @@ -670,6 +671,7 @@ int main(int argc, char **argv) if (arch == CS_ARCH_ALL) { fprintf(stderr, "ERROR: Invalid : \"%s\", quit!\n", choosen_arch); usage(argv[0]); + free(assembly); return -1; } @@ -677,6 +679,7 @@ int main(int argc, char **argv) const char *error = cs_strerror(err); fprintf(stderr, "ERROR: Failed on cs_open(): %s\n", error); usage(argv[0]); + free(assembly); return -1; } diff --git a/tests/issues/fuzzing.yaml b/tests/issues/fuzzing.yaml new file mode 100644 index 0000000000..85c66e26d6 --- /dev/null +++ b/tests/issues/fuzzing.yaml @@ -0,0 +1,29 @@ +test_cases: + - + input: + name: "OOB read should be 2 bytes" + bytes: [ 0x00 ] + arch: "CS_ARCH_SYSTEMZ" + options: [ CS_MODE_BIG_ENDIAN ] + address: 0x0 + expected: + insns: [] + - + input: + name: "OOB read should be 4 bytes" + bytes: [ 0xb0, 0xff ] + arch: "CS_ARCH_SYSTEMZ" + options: [ CS_MODE_BIG_ENDIAN ] + address: 0x0 + expected: + insns: [] + - + input: + name: "OOB read should be 6 bytes" + bytes: [ 0xc0, 0xff, 0xff ] + arch: "CS_ARCH_SYSTEMZ" + options: [ CS_MODE_BIG_ENDIAN ] + address: 0x0 + expected: + insns: [] +