diff options
| author | 2023-01-18 19:29:48 +0100 | |
|---|---|---|
| committer | 2023-01-18 19:29:48 +0100 | |
| commit | 4c8844d2c55a1ec05fa50f5b76c0b8baeece134c (patch) | |
| tree | 43652a63fc6ae9d58f81706832f32c95689cfa06 | |
| parent | 85f5cbd3705b34fcc52009ca51d8167ab18764fa (diff) | |
| download | libplist-4c8844d2c55a1ec05fa50f5b76c0b8baeece134c.tar.gz libplist-4c8844d2c55a1ec05fa50f5b76c0b8baeece134c.tar.bz2 | |
oplist: Prevent too many levels of recursion to prevent stack overflow
Credit to OSS-Fuzz
| -rw-r--r-- | src/oplist.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/oplist.c b/src/oplist.c index 4dd0df5..420cbd6 100644 --- a/src/oplist.c +++ b/src/oplist.c | |||
| @@ -480,6 +480,7 @@ struct _parse_ctx { | |||
| 480 | const char *pos; | 480 | const char *pos; |
| 481 | const char *end; | 481 | const char *end; |
| 482 | int err; | 482 | int err; |
| 483 | uint32_t depth; | ||
| 483 | }; | 484 | }; |
| 484 | typedef struct _parse_ctx* parse_ctx; | 485 | typedef struct _parse_ctx* parse_ctx; |
| 485 | 486 | ||
| @@ -597,6 +598,12 @@ static int node_from_openstep(parse_ctx ctx, plist_t *plist) | |||
| 597 | { | 598 | { |
| 598 | plist_t subnode = NULL; | 599 | plist_t subnode = NULL; |
| 599 | const char *p = NULL; | 600 | const char *p = NULL; |
| 601 | ctx->depth++; | ||
| 602 | if (ctx->depth > 1000) { | ||
| 603 | PLIST_OSTEP_ERR("Too many levels of recursion (%u) at offset %ld\n", ctx->depth, ctx->pos - ctx->start); | ||
| 604 | ctx->err++; | ||
| 605 | return PLIST_ERR_PARSE; | ||
| 606 | } | ||
| 600 | while (ctx->pos < ctx->end && !ctx->err) { | 607 | while (ctx->pos < ctx->end && !ctx->err) { |
| 601 | parse_skip_ws(ctx); | 608 | parse_skip_ws(ctx); |
| 602 | if (ctx->pos >= ctx->end) { | 609 | if (ctx->pos >= ctx->end) { |
| @@ -867,6 +874,7 @@ static int node_from_openstep(parse_ctx ctx, plist_t *plist) | |||
| 867 | } | 874 | } |
| 868 | ctx->pos++; | 875 | ctx->pos++; |
| 869 | } | 876 | } |
| 877 | ctx->depth--; | ||
| 870 | 878 | ||
| 871 | err_out: | 879 | err_out: |
| 872 | if (ctx->err) { | 880 | if (ctx->err) { |
| @@ -888,7 +896,7 @@ PLIST_API int plist_from_openstep(const char *plist_ostep, uint32_t length, plis | |||
| 888 | return PLIST_ERR_INVALID_ARG; | 896 | return PLIST_ERR_INVALID_ARG; |
| 889 | } | 897 | } |
| 890 | 898 | ||
| 891 | struct _parse_ctx ctx = { plist_ostep, plist_ostep, plist_ostep + length, 0 }; | 899 | struct _parse_ctx ctx = { plist_ostep, plist_ostep, plist_ostep + length, 0 , 0 }; |
| 892 | 900 | ||
| 893 | int err = node_from_openstep(&ctx, plist); | 901 | int err = node_from_openstep(&ctx, plist); |
| 894 | if (err == 0) { | 902 | if (err == 0) { |
