Skip to content

Commit 4d90b13

Browse files
authored
CVE v5 backports (#2835)
* Backport of 2c77971 to v5 branch. * Check return value of cs_vsnprintf for negative values. This prevents underflow of SStream.index. This bug was reported by Github user Finder16. * Add overflow check before adding cs_vsnprintf return value. * Backport of cbef767 into v5. The overflow was reported by Github user Finder16
1 parent cd6dd7b commit 4d90b13

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

SStream.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void SStream_concat0(SStream *ss, const char *s)
3333
#ifndef CAPSTONE_DIET
3434
unsigned int len = (unsigned int) strlen(s);
3535

36+
SSTREAM_OVERFLOW_CHECK(ss, len);
3637
memcpy(ss->buffer + ss->index, s, len);
3738
ss->index += len;
3839
ss->buffer[ss->index] = '\0';
@@ -42,6 +43,7 @@ void SStream_concat0(SStream *ss, const char *s)
4243
void SStream_concat1(SStream *ss, const char c)
4344
{
4445
#ifndef CAPSTONE_DIET
46+
SSTREAM_OVERFLOW_CHECK(ss, 1);
4547
ss->buffer[ss->index] = c;
4648
ss->index++;
4749
ss->buffer[ss->index] = '\0';
@@ -57,6 +59,10 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
5759
va_start(ap, fmt);
5860
ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
5961
va_end(ap);
62+
if (ret < 0) {
63+
return;
64+
}
65+
SSTREAM_OVERFLOW_CHECK(ss, ret);
6066
ss->index += ret;
6167
#endif
6268
}

SStream.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@
66

77
#include "include/capstone/platform.h"
88

9+
#define SSTREAM_BUF_LEN 512
10+
11+
#define SSTREAM_OVERFLOW_CHECK(OS, len) \
12+
do { \
13+
if (OS->index + len + 1 > SSTREAM_BUF_LEN) { \
14+
fprintf(stderr, "Buffer overflow caught!\n"); \
15+
return; \
16+
} \
17+
} while (0)
18+
919
typedef struct SStream {
10-
char buffer[512];
20+
char buffer[SSTREAM_BUF_LEN];
1121
int index;
1222
} SStream;
1323

cs.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -976,10 +976,13 @@ size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64
976976
skipdata_bytes = handle->skipdata_size;
977977

978978
// we have to skip some amount of data, depending on arch & mode
979-
insn_cache->id = 0; // invalid ID for this "data" instruction
979+
// invalid ID for this "data" instruction
980+
insn_cache->id = 0;
980981
insn_cache->address = offset;
981-
insn_cache->size = (uint16_t)skipdata_bytes;
982-
memcpy(insn_cache->bytes, buffer, skipdata_bytes);
982+
insn_cache->size = (uint16_t)MIN(
983+
skipdata_bytes, sizeof(insn_cache->bytes));
984+
memcpy(insn_cache->bytes, buffer,
985+
MIN(skipdata_bytes, sizeof(insn_cache->bytes)));
983986
#ifdef CAPSTONE_DIET
984987
insn_cache->mnemonic[0] = '\0';
985988
insn_cache->op_str[0] = '\0';
@@ -1181,12 +1184,13 @@ bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
11811184
// we have to skip some amount of data, depending on arch & mode
11821185
insn->id = 0; // invalid ID for this "data" instruction
11831186
insn->address = *address;
1184-
insn->size = (uint16_t)skipdata_bytes;
1187+
insn->size = (uint16_t)MIN(skipdata_bytes, sizeof(insn->bytes));
1188+
memcpy(insn->bytes, *code,
1189+
MIN(skipdata_bytes, sizeof(insn->bytes)));
11851190
#ifdef CAPSTONE_DIET
11861191
insn->mnemonic[0] = '\0';
11871192
insn->op_str[0] = '\0';
11881193
#else
1189-
memcpy(insn->bytes, *code, skipdata_bytes);
11901194
strncpy(insn->mnemonic, handle->skipdata_setup.mnemonic,
11911195
sizeof(insn->mnemonic) - 1);
11921196
skipdata_opstr(insn->op_str, *code, skipdata_bytes);

0 commit comments

Comments
 (0)