Skip to content

Commit

Permalink
Protect privileged demangler from stack overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Nov 24, 2024
1 parent ef00a7d commit 5fae582
Showing 1 changed file with 51 additions and 5 deletions.
56 changes: 51 additions & 5 deletions libc/intrin/demangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Copyright (c) 2024 Justine Tunney <[email protected]>");
#define ELFTC_SUCCESS 1

#define VECTOR_DEF_CAPACITY 1
#define MAX_DEPTH 20

typedef unsigned short index_t;

Expand Down Expand Up @@ -188,6 +189,7 @@ struct demangle_data {
enum type_qualifier ref_qualifier_type; /* ref qualifier type */
enum push_qualifier push_qualifier; /* which qualifiers to push */
int func_type;
int depth;
const char *cur; /* current mangled name ptr */
const char *last_sname; /* last source name */
intptr_t jmpbuf[5];
Expand Down Expand Up @@ -2261,7 +2263,7 @@ demangle_read_expression_binary(struct demangle_data *ddata, const char *name,
}

static privileged int
demangle_read_expression(struct demangle_data *ddata)
demangle_read_expression_impl(struct demangle_data *ddata)
{
if (*ddata->cur == '\0')
return 0;
Expand Down Expand Up @@ -2542,6 +2544,17 @@ demangle_read_expression(struct demangle_data *ddata)
return 0;
}

static privileged int
demangle_read_expression(struct demangle_data *ddata)
{
if (ddata->depth == MAX_DEPTH)
__builtin_longjmp(ddata->jmpbuf, 1);
++ddata->depth;
int res = demangle_read_expression_impl(ddata);
--ddata->depth;
return res;
}

static privileged int
demangle_read_expression_flat(struct demangle_data *ddata, char **str)
{
Expand Down Expand Up @@ -2891,9 +2904,8 @@ demangle_read_number_as_string(struct demangle_data *ddata, char **str)
return 1;
}

/* read encoding, encoding are function name, data name, special-name */
static privileged int
demangle_read_encoding(struct demangle_data *ddata)
demangle_read_encoding_impl(struct demangle_data *ddata)
{
char *name, *type, *num_str;
long offset;
Expand Down Expand Up @@ -3100,6 +3112,18 @@ demangle_read_encoding(struct demangle_data *ddata)
return demangle_read_name(ddata);
}

/* read encoding, encoding are function name, data name, special-name */
static privileged int
demangle_read_encoding(struct demangle_data *ddata)
{
if (ddata->depth == MAX_DEPTH)
__builtin_longjmp(ddata->jmpbuf, 1);
++ddata->depth;
int res = demangle_read_encoding_impl(ddata);
--ddata->depth;
return res;
}

static privileged int
demangle_read_local_name(struct demangle_data *ddata)
{
Expand Down Expand Up @@ -3270,7 +3294,7 @@ demangle_read_nested_name(struct demangle_data *ddata)
}

static privileged int
demangle_read_name(struct demangle_data *ddata)
demangle_read_name_impl(struct demangle_data *ddata)
{
struct stack_str v;
struct vector_str *output;
Expand Down Expand Up @@ -3331,6 +3355,17 @@ demangle_read_name(struct demangle_data *ddata)
return rtn;
}

static privileged int
demangle_read_name(struct demangle_data *ddata)
{
if (ddata->depth == MAX_DEPTH)
__builtin_longjmp(ddata->jmpbuf, 1);
++ddata->depth;
int res = demangle_read_name_impl(ddata);
--ddata->depth;
return res;
}

static privileged int
demangle_read_name_flat(struct demangle_data *ddata, char **str)
{
Expand Down Expand Up @@ -3697,7 +3732,7 @@ demangle_vector_type_qualifier_push(struct demangle_data *ddata,
}

static privileged int
demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
demangle_read_type_impl(struct demangle_data *ddata, struct type_delimit *td)
{
struct vector_type_qualifier v;
struct vector_str *output, sv;
Expand Down Expand Up @@ -4219,6 +4254,17 @@ demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
return 0;
}

static privileged int
demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
{
if (ddata->depth == MAX_DEPTH)
__builtin_longjmp(ddata->jmpbuf, 1);
++ddata->depth;
int res = demangle_read_type_impl(ddata, td);
--ddata->depth;
return res;
}

static privileged int
demangle_copy_output(struct demangle_data *ddata, char *buf,
const struct vector_str *v, size_t buflen)
Expand Down

0 comments on commit 5fae582

Please sign in to comment.