From 4c8844d2c55a1ec05fa50f5b76c0b8baeece134c Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Wed, 18 Jan 2023 19:29:48 +0100 Subject: oplist: Prevent too many levels of recursion to prevent stack overflow Credit to OSS-Fuzz --- src/oplist.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 { const char *pos; const char *end; int err; + uint32_t depth; }; typedef struct _parse_ctx* parse_ctx; @@ -597,6 +598,12 @@ static int node_from_openstep(parse_ctx ctx, plist_t *plist) { plist_t subnode = NULL; const char *p = NULL; + ctx->depth++; + if (ctx->depth > 1000) { + PLIST_OSTEP_ERR("Too many levels of recursion (%u) at offset %ld\n", ctx->depth, ctx->pos - ctx->start); + ctx->err++; + return PLIST_ERR_PARSE; + } while (ctx->pos < ctx->end && !ctx->err) { parse_skip_ws(ctx); if (ctx->pos >= ctx->end) { @@ -867,6 +874,7 @@ static int node_from_openstep(parse_ctx ctx, plist_t *plist) } ctx->pos++; } + ctx->depth--; err_out: if (ctx->err) { @@ -888,7 +896,7 @@ PLIST_API int plist_from_openstep(const char *plist_ostep, uint32_t length, plis return PLIST_ERR_INVALID_ARG; } - struct _parse_ctx ctx = { plist_ostep, plist_ostep, plist_ostep + length, 0 }; + struct _parse_ctx ctx = { plist_ostep, plist_ostep, plist_ostep + length, 0 , 0 }; int err = node_from_openstep(&ctx, plist); if (err == 0) { -- cgit v1.1-32-gdbae