diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2022-11-09 11:14:12 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2022-11-09 12:08:20 -0500 |
commit | b41dca52762c5188638236ae81b9f4597bb29ac9 (patch) | |
tree | 4d503f6dcee1b1ed15ef61df3c8ccb9b92533546 /src/opt.c | |
parent | dd6808539013061a3113e45c7267430e56749f2c (diff) | |
download | bfs-b41dca52762c5188638236ae81b9f4597bb29ac9.tar.xz |
pwcache: Fill the user/group caches lazily
Iterating all the users/groups can be expensive, especially with NSS.
Android has so many that it doesn't even return them all from
get{pw,gr}ent() for performance reasons, leading to incorrect behaviour
of -user/-group/etc.
Diffstat (limited to 'src/opt.c')
-rw-r--r-- | src/opt.c | 19 |
1 files changed, 11 insertions, 8 deletions
@@ -48,6 +48,7 @@ #include "expr.h" #include "pwcache.h" #include <assert.h> +#include <errno.h> #include <limits.h> #include <stdarg.h> #include <stdbool.h> @@ -789,12 +790,13 @@ static void infer_icmp_facts(struct opt_state *state, const struct bfs_expr *exp static void infer_gid_facts(struct opt_state *state, const struct bfs_expr *expr) { infer_icmp_facts(state, expr, GID_RANGE); - const struct bfs_groups *groups = bfs_ctx_groups(state->ctx); struct range *range = &state->facts_when_true.ranges[GID_RANGE]; - if (groups && range->min == range->max) { + if (range->min == range->max) { gid_t gid = range->min; - bool nogroup = !bfs_getgrgid(groups, gid); - constrain_pred(&state->facts_when_true.preds[NOGROUP_PRED], nogroup); + bool nogroup = !bfs_getgrgid(state->ctx->groups, gid); + if (errno == 0) { + constrain_pred(&state->facts_when_true.preds[NOGROUP_PRED], nogroup); + } } } @@ -802,12 +804,13 @@ static void infer_gid_facts(struct opt_state *state, const struct bfs_expr *expr static void infer_uid_facts(struct opt_state *state, const struct bfs_expr *expr) { infer_icmp_facts(state, expr, UID_RANGE); - const struct bfs_users *users = bfs_ctx_users(state->ctx); struct range *range = &state->facts_when_true.ranges[UID_RANGE]; - if (users && range->min == range->max) { + if (range->min == range->max) { uid_t uid = range->min; - bool nouser = !bfs_getpwuid(users, uid); - constrain_pred(&state->facts_when_true.preds[NOUSER_PRED], nouser); + bool nouser = !bfs_getpwuid(state->ctx->users, uid); + if (errno == 0) { + constrain_pred(&state->facts_when_true.preds[NOUSER_PRED], nouser); + } } } |