Mercurial > hg > dhcpcd
changeset 5249:a8c2969955f9 draft
privsep: Only allow file IO to specific paths
In the same vein as filtering ioctls.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Thu, 21 May 2020 12:54:58 +0100 |
| parents | af220d1d4c92 |
| children | 698ca745f939 |
| files | src/privsep-root.c |
| diffstat | 1 files changed, 30 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/privsep-root.c Wed May 20 21:43:20 2020 +0100 +++ b/src/privsep-root.c Thu May 21 12:54:58 2020 +0100 @@ -304,8 +304,25 @@ return status; } +static bool +ps_root_validpath(const struct dhcpcd_ctx *ctx, uint16_t cmd, const char *path) +{ + + if (cmd == PS_READFILE) { + if (strcmp(ctx->cffile, path) == 0) + return true; + } + if (strncmp(DBDIR, path, strlen(DBDIR)) == 0) + return true; + if (strncmp(RUNDIR, path, strlen(RUNDIR)) == 0) + return true; + errno = EPERM; + return false; +} + static ssize_t -ps_root_dowritefile(mode_t mode, void *data, size_t len) +ps_root_dowritefile(const struct dhcpcd_ctx *ctx, + mode_t mode, void *data, size_t len) { char *file = data, *nc; @@ -314,6 +331,8 @@ errno = EINVAL; return -1; } + if (!ps_root_validpath(ctx, PS_WRITEFILE, file)) + return -1; nc++; return writefile(file, mode, nc, len - (size_t)(nc - file)); } @@ -480,9 +499,17 @@ err = ps_root_run_script(ctx, data, len); break; case PS_UNLINK: + if (!ps_root_validpath(ctx, psm->ps_cmd, data)) { + err = -1; + break; + } err = unlink(data); break; case PS_READFILE: + if (!ps_root_validpath(ctx, psm->ps_cmd, data)) { + err = -1; + break; + } err = readfile(data, buf, sizeof(buf)); if (err != -1) { rdata = buf; @@ -490,7 +517,8 @@ } break; case PS_WRITEFILE: - err = ps_root_dowritefile((mode_t)psm->ps_flags, data, len); + err = ps_root_dowritefile(ctx, (mode_t)psm->ps_flags, + data, len); break; case PS_FILEMTIME: err = filemtime(data, &mtime);
