diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-02-06 23:18:11 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-02-06 23:18:11 -0500 |
commit | 9009456c1ad07f8cd781c21c9d63bde354da7d41 (patch) | |
tree | f8e9bf1315fa77fa648ee28963a5b94cf7ea7a3f | |
parent | d53a1b6b572370e303e42e9238abc458d4c22b64 (diff) | |
download | bfs-9009456c1ad07f8cd781c21c9d63bde354da7d41.tar.xz |
Fix -nouser/-nogroup error handling
The proper way to check for nonexistent users/groups is to set errno to
0 before the get{grg,pwu}id() call, and check it afterwards.
On doing this, it becomes obvious that the call can fail if bftw() is
using all the available FDs, so give them some ephemeral FDs. It would
be ideal to read the user/group table only once, but this fixes the bug
for now.
-rw-r--r-- | eval.c | 22 | ||||
-rw-r--r-- | parse.c | 2 |
2 files changed, 22 insertions, 2 deletions
@@ -369,7 +369,16 @@ bool eval_nogroup(const struct expr *expr, struct eval_state *state) { return false; } - return getgrgid(statbuf->gid) == NULL; + errno = 0; + if (getgrgid(statbuf->gid) == NULL) { + if (errno == 0) { + return true; + } else { + eval_report_error(state); + } + } + + return false; } /** @@ -381,7 +390,16 @@ bool eval_nouser(const struct expr *expr, struct eval_state *state) { return false; } - return getpwuid(statbuf->uid) == NULL; + errno = 0; + if (getpwuid(statbuf->uid) == NULL) { + if (errno == 0) { + return true; + } else { + eval_report_error(state); + } + } + + return false; } /** @@ -1658,6 +1658,7 @@ static struct expr *parse_nogroup(struct parser_state *state, int arg1, int arg2 struct expr *expr = parse_nullary_test(state, eval_nogroup); if (expr) { expr->cost = 9000.0; + expr->ephemeral_fds = 1; } return expr; } @@ -1688,6 +1689,7 @@ static struct expr *parse_nouser(struct parser_state *state, int arg1, int arg2) struct expr *expr = parse_nullary_test(state, eval_nouser); if (expr) { expr->cost = 9000.0; + expr->ephemeral_fds = 1; } return expr; } |