summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2023-01-18 19:29:48 +0100
committerGravatar Nikias Bassen2023-01-18 19:29:48 +0100
commit4c8844d2c55a1ec05fa50f5b76c0b8baeece134c (patch)
tree43652a63fc6ae9d58f81706832f32c95689cfa06
parent85f5cbd3705b34fcc52009ca51d8167ab18764fa (diff)
downloadlibplist-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.c10
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 {
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) {