Skip to content

Commit

Permalink
Fix integer overflow in gnuv2 c++ demangler.
Browse files Browse the repository at this point in the history
  • Loading branch information
wargio committed Apr 1, 2024
1 parent 029fdd3 commit 498e007
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions src/gnu_v2/cplus-dem.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define UT32_MAX 0xffffffffu

#include "cplus-dem.h"
#undef CURRENT_DEMANGLING_STYLE
Expand Down Expand Up @@ -408,6 +411,20 @@ static const char *
static const char *
demangle_qualifier PARAMS((int));

#define overflow_check_mul(a, b) \
do { \
if ((b) && (a) > (UT32_MAX / (b))) { \
return -1; \
} \
} while (0)

#define overflow_check_add(a, b) \
do { \
if ((a) > (UT32_MAX - (b))) { \
return -1; \
} \
} while (0)

/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.
Expand All @@ -423,26 +440,19 @@ static int
// Note by RizinOrg:
// to prevent the overflow check to be optimized out
// by the compiler, this variable needs to be volatile.
volatile int count = 0;
uint32_t count = 0;

if (!isdigit((unsigned char)**type))
return -1;

while (isdigit((unsigned char)**type)) {
overflow_check_mul(count, 10);
count *= 10;

/* Check for overflow.
We assume that count is represented using two's-complement;
no power of two is divisible by ten, so if an overflow occurs
when multiplying by ten, the result will not be a multiple of
ten. */
if ((count % 10) != 0) {
while (isdigit((unsigned char)**type))
(*type)++;
return -1;
}
uint32_t num = **type - '0';
overflow_check_add(count, num);
count += num;

count += **type - '0';
(*type)++;
}

Expand Down

0 comments on commit 498e007

Please sign in to comment.