X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/yaid/blobdiff_plain/17272ab8669aa3061b08de9862ea1e9086b8b540..429dcd8d6a215be133a0b587b69516197922b9ff:/policy.c diff --git a/policy.c b/policy.c index 57ce979..9cb9af9 100644 --- a/policy.c +++ b/policy.c @@ -441,6 +441,11 @@ fail: /* Open a policy file by NAME. The description WHAT and query Q are used for * formatting error messages for the log. + * + * This function is somewhat careful only to read from actual regular files, + * though (if the filesystem object identified by NAME is a symlink, say) it + * might open a device node or other exotic thing without reading it. This + * is likely harmless, since we're running as an unprivileged user anyway. */ int open_policy_file(struct policy_file *pf, const char *name, const char *what, const struct query *q, unsigned f) @@ -492,22 +497,20 @@ int read_policy_file(struct policy_file *pf) t = parse_policy(pf->fp, &pf->p); switch (t) { case T_OK: + case T_EOL: nextline(pf->fp); - return (0); + return (t); case T_ERROR: logmsg(pf->q, LOG_ERR, "%s:%d: parse error in %s", pf->name, pf->lno, pf->what); pf->err = 1; - break; + return (t); case T_EOF: if (ferror(pf->fp)) { logmsg(pf->q, LOG_ERR, "failed to read %s `%s': %s", pf->what, pf->name, strerror(errno)); } - return (-1); - case T_EOL: - nextline(pf->fp); - break; + return (t); default: abort(); } @@ -530,12 +533,15 @@ int load_policy_file(const char *file, policy_v *pv) { struct policy_file pf; policy_v v = DA_INIT; + int t = 0; if (open_policy_file(&pf, file, "policy file", 0, 0)) return (-1); - while (!read_policy_file(&pf)) { - DA_PUSH(&v, pf.p); - init_policy(&pf.p); + while ((t = read_policy_file(&pf)) < T_EOF) { + if (t == T_OK) { + DA_PUSH(&v, pf.p); + init_policy(&pf.p); + } } close_policy_file(&pf); if (!pf.err) {