From 666bd94f932ec6f1b031f3220bbc9f55ca83c409 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 20 Jun 2025 09:37:11 -0400 Subject: opt: "Not me" doesn't imply "nobody" We were making `-user ` imply `! -nouser`, which is valid, but we were also makeing `! -user ` imply `-nouser`, which isn't. Fix it by only constraining the `-nouser`/`-nogroup` predicates in the true case. While I'm here, fix a similar latent bug that would have triggered if we ever merged `-readable -and -writable` into one `R_OK | W_OK` test. Fixes: https://github.com/tavianator/bfs/issues/155 Fixes: 305ee902 ("opt: Track data flow information about predicates") --- src/opt.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/opt.c b/src/opt.c index 49e8873..9094794 100644 --- a/src/opt.c +++ b/src/opt.c @@ -1623,14 +1623,19 @@ static void data_flow_icmp(struct bfs_opt *opt, const struct bfs_expr *expr, enu /** Transfer function for -{execut,read,writ}able. */ static struct bfs_expr *data_flow_access(struct bfs_opt *opt, struct bfs_expr *expr, const struct visitor *visitor) { - if (expr->num & R_OK) { + switch (expr->num) { + case R_OK: data_flow_pred(opt, READABLE_PRED, true); - } - if (expr->num & W_OK) { + break; + case W_OK: data_flow_pred(opt, WRITABLE_PRED, true); - } - if (expr->num & X_OK) { + break; + case X_OK: data_flow_pred(opt, EXECUTABLE_PRED, true); + break; + default: + bfs_bug("Unknown access() mode %lld", expr->num); + break; } return expr; @@ -1655,7 +1660,7 @@ static struct bfs_expr *data_flow_gid(struct bfs_opt *opt, struct bfs_expr *expr gid_t gid = range->min; bool nogroup = !bfs_getgrgid(opt->ctx->groups, gid); if (errno == 0) { - data_flow_pred(opt, NOGROUP_PRED, nogroup); + constrain_pred(&opt->after_true.preds[NOGROUP_PRED], nogroup); } } @@ -1729,7 +1734,7 @@ static struct bfs_expr *data_flow_uid(struct bfs_opt *opt, struct bfs_expr *expr uid_t uid = range->min; bool nouser = !bfs_getpwuid(opt->ctx->users, uid); if (errno == 0) { - data_flow_pred(opt, NOUSER_PRED, nouser); + constrain_pred(&opt->after_true.preds[NOUSER_PRED], nouser); } } -- cgit v1.2.3