From: Mark Wooding Date: Wed, 17 Jul 2024 12:04:52 +0000 (+0100) Subject: checkpath.c: Allocate the state from a resource pool. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/checkpath/commitdiff_plain/c7ade76f8e82fb51068cfd9e41b8268b35c50b13 checkpath.c: Allocate the state from a resource pool. I think you can see where this is going. --- diff --git a/checkpath.c b/checkpath.c index e4d83e1..95524ae 100644 --- a/checkpath.c +++ b/checkpath.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "checkpath.h" @@ -64,6 +65,7 @@ struct elt { }; struct state { + pool *p; /* Allocation pool */ struct elt *sp; /* Stack pointer for list */ dstr path; /* Current path string */ }; @@ -355,7 +357,8 @@ unsigned checkpath(const char *p, const struct checkpath *cp) { char cwd[PATH_MAX]; struct elt *e, *ee; - struct state state; + struct state *state; + pool *pp; struct stat st; unsigned bad = 0; dstr buf = DSTR_INIT; @@ -363,8 +366,11 @@ unsigned checkpath(const char *p, const struct checkpath *cp) /* --- Initialize the state --- */ - state.sp = (/*unconst*/ struct elt *)&rootnode; - dstr_create(&state.path); + pp = pool_create(arena_global); + state = pool_alloc(pp, sizeof(*state)); + state->p = pp; + state->sp = (/*unconst*/ struct elt *)&rootnode; + dstr_create(&state->path); /* --- Try to find the current directory --- */ @@ -405,7 +411,7 @@ unsigned checkpath(const char *p, const struct checkpath *cp) /* --- Backtrack on `..' elements --- */ else if (strcmp(ee->e_name, "..") == 0) { - pop(&state); + pop(state); xfree(ee); ee = e; continue; @@ -413,13 +419,13 @@ unsigned checkpath(const char *p, const struct checkpath *cp) /* --- Everything else gets pushed on the end --- */ - push(&state, ee); + push(state, ee); ee = e; /* --- Find out what sort of a thing this is --- */ - if (lstat(state.path.buf, &st)) { - report(cp, CP_ERROR, 0, state.path.buf, "can't stat: %e"); + if (lstat(state->path.buf, &st)) { + report(cp, CP_ERROR, 0, state->path.buf, "can't stat: %e"); bad |= CP_ERROR; break; } @@ -432,13 +438,13 @@ unsigned checkpath(const char *p, const struct checkpath *cp) dstr_reset(&buf); dstr_ensure(&buf, st.st_size + 1); - if ((i = readlink(state.path.buf, buf.buf, buf.sz)) < 0) { - report(cp, CP_ERROR, 0, state.path.buf, "can't readlink: %e"); + if ((i = readlink(state->path.buf, buf.buf, buf.sz)) < 0) { + report(cp, CP_ERROR, 0, state->path.buf, "can't readlink: %e"); bad |= CP_ERROR; break; } buf.buf[i] = 0; - report(cp, CP_SYMLINK, 2, state.path.buf, "symlink -> `%s'", buf.buf); + report(cp, CP_SYMLINK, 2, state->path.buf, "symlink -> `%s'", buf.buf); /* --- Handle sticky parents --- * * @@ -448,31 +454,31 @@ unsigned checkpath(const char *p, const struct checkpath *cp) */ if ((cp->cp_what & CP_WROTHUSR) && - (state.sp->e_link->e_flags & EF_STICKY) && + (state->sp->e_link->e_flags & EF_STICKY) && st.st_uid != cp->cp_uid && st.st_uid != 0) { bad |= CP_WROTHUSR; - report(cp, CP_WROTHUSR, 1, state.path.buf, + report(cp, CP_WROTHUSR, 1, state->path.buf, "symlink modifiable by user %u", st.st_uid); } /* --- Sort out what to do from here --- */ if (buf.buf[0] == '/') - popall(&state); + popall(state); else - pop(&state); + pop(state); ee = splitpath(buf.buf, ee); continue; } /* --- Run the sanity check on this path element --- */ - bad |= sanity(state.path.buf, &st, cp, ee ? 0 : SF_LAST); + bad |= sanity(state->path.buf, &st, cp, ee ? 0 : SF_LAST); if (S_ISDIR(st.st_mode)) { if (st.st_mode & S_ISVTX) - state.sp->e_flags |= EF_STICKY; - report(cp, CP_REPORT, 4, state.path.buf, "directory"); + state->sp->e_flags |= EF_STICKY; + report(cp, CP_REPORT, 4, state->path.buf, "directory"); continue; } @@ -493,9 +499,10 @@ unsigned checkpath(const char *p, const struct checkpath *cp) } } - popall(&state); - dstr_destroy(&state.path); + popall(state); + dstr_destroy(&state->path); dstr_destroy(&buf); + pool_destroy(state->p); return (bad); }