Skip to content

Commit 5fae582

Browse files
committed
Protect privileged demangler from stack overflow
1 parent ef00a7d commit 5fae582

File tree

1 file changed

+51
-5
lines changed

1 file changed

+51
-5
lines changed

libc/intrin/demangle.c

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Copyright (c) 2024 Justine Tunney <[email protected]>");
103103
#define ELFTC_SUCCESS 1
104104

105105
#define VECTOR_DEF_CAPACITY 1
106+
#define MAX_DEPTH 20
106107

107108
typedef unsigned short index_t;
108109

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

22632265
static privileged int
2264-
demangle_read_expression(struct demangle_data *ddata)
2266+
demangle_read_expression_impl(struct demangle_data *ddata)
22652267
{
22662268
if (*ddata->cur == '\0')
22672269
return 0;
@@ -2542,6 +2544,17 @@ demangle_read_expression(struct demangle_data *ddata)
25422544
return 0;
25432545
}
25442546

2547+
static privileged int
2548+
demangle_read_expression(struct demangle_data *ddata)
2549+
{
2550+
if (ddata->depth == MAX_DEPTH)
2551+
__builtin_longjmp(ddata->jmpbuf, 1);
2552+
++ddata->depth;
2553+
int res = demangle_read_expression_impl(ddata);
2554+
--ddata->depth;
2555+
return res;
2556+
}
2557+
25452558
static privileged int
25462559
demangle_read_expression_flat(struct demangle_data *ddata, char **str)
25472560
{
@@ -2891,9 +2904,8 @@ demangle_read_number_as_string(struct demangle_data *ddata, char **str)
28912904
return 1;
28922905
}
28932906

2894-
/* read encoding, encoding are function name, data name, special-name */
28952907
static privileged int
2896-
demangle_read_encoding(struct demangle_data *ddata)
2908+
demangle_read_encoding_impl(struct demangle_data *ddata)
28972909
{
28982910
char *name, *type, *num_str;
28992911
long offset;
@@ -3100,6 +3112,18 @@ demangle_read_encoding(struct demangle_data *ddata)
31003112
return demangle_read_name(ddata);
31013113
}
31023114

3115+
/* read encoding, encoding are function name, data name, special-name */
3116+
static privileged int
3117+
demangle_read_encoding(struct demangle_data *ddata)
3118+
{
3119+
if (ddata->depth == MAX_DEPTH)
3120+
__builtin_longjmp(ddata->jmpbuf, 1);
3121+
++ddata->depth;
3122+
int res = demangle_read_encoding_impl(ddata);
3123+
--ddata->depth;
3124+
return res;
3125+
}
3126+
31033127
static privileged int
31043128
demangle_read_local_name(struct demangle_data *ddata)
31053129
{
@@ -3270,7 +3294,7 @@ demangle_read_nested_name(struct demangle_data *ddata)
32703294
}
32713295

32723296
static privileged int
3273-
demangle_read_name(struct demangle_data *ddata)
3297+
demangle_read_name_impl(struct demangle_data *ddata)
32743298
{
32753299
struct stack_str v;
32763300
struct vector_str *output;
@@ -3331,6 +3355,17 @@ demangle_read_name(struct demangle_data *ddata)
33313355
return rtn;
33323356
}
33333357

3358+
static privileged int
3359+
demangle_read_name(struct demangle_data *ddata)
3360+
{
3361+
if (ddata->depth == MAX_DEPTH)
3362+
__builtin_longjmp(ddata->jmpbuf, 1);
3363+
++ddata->depth;
3364+
int res = demangle_read_name_impl(ddata);
3365+
--ddata->depth;
3366+
return res;
3367+
}
3368+
33343369
static privileged int
33353370
demangle_read_name_flat(struct demangle_data *ddata, char **str)
33363371
{
@@ -3697,7 +3732,7 @@ demangle_vector_type_qualifier_push(struct demangle_data *ddata,
36973732
}
36983733

36993734
static privileged int
3700-
demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
3735+
demangle_read_type_impl(struct demangle_data *ddata, struct type_delimit *td)
37013736
{
37023737
struct vector_type_qualifier v;
37033738
struct vector_str *output, sv;
@@ -4219,6 +4254,17 @@ demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
42194254
return 0;
42204255
}
42214256

4257+
static privileged int
4258+
demangle_read_type(struct demangle_data *ddata, struct type_delimit *td)
4259+
{
4260+
if (ddata->depth == MAX_DEPTH)
4261+
__builtin_longjmp(ddata->jmpbuf, 1);
4262+
++ddata->depth;
4263+
int res = demangle_read_type_impl(ddata, td);
4264+
--ddata->depth;
4265+
return res;
4266+
}
4267+
42224268
static privileged int
42234269
demangle_copy_output(struct demangle_data *ddata, char *buf,
42244270
const struct vector_str *v, size_t buflen)

0 commit comments

Comments
 (0)