From cf00568d888c90a8c5d06a06283bc87a45992933 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 26 Aug 2023 10:32:37 -0600 Subject: [PATCH] Do not rely on the definition of ALLOW/DENY being true/false. We now explicitly check for ALLOW and DENY when checking return values and negating values. Reference: https://github.com/sudo-project/sudo/commit/cf00568d888c90a8c5d06a06283bc87a45992933 Conflict: cvtsudoers.c match.c --- plugins/sudoers/cvtsudoers.c | 6 +-- plugins/sudoers/match.c | 83 +++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c index 79558c3..8cedcc6 100644 --- a/plugins/sudoers/cvtsudoers.c +++ b/plugins/sudoers/cvtsudoers.c @@ -690,7 +690,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree, pw.pw_uid = (uid_t)-1; pw.pw_gid = (gid_t)-1; - if (user_matches(parse_tree, &pw, m) == true) + if (user_matches(parse_tree, &pw, m) == ALLOW) matched = true; } else { STAILQ_FOREACH(s, &filters->users, entries) { @@ -716,7 +716,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree, if (pw == NULL) continue; - if (user_matches(parse_tree, pw, m) == true) + if (user_matches(parse_tree, pw, m) == ALLOW) matched = true; sudo_pw_delref(pw); @@ -792,7 +792,7 @@ hostlist_matches_filter(struct sudoers_parse_tree *parse_tree, /* Only need one host in the filter to match. */ /* XXX - can't use netgroup_tuple with NULL pw */ - if (host_matches(parse_tree, NULL, lhost, shost, m) == true) { + if (host_matches(parse_tree, NULL, lhost, shost, m) == ALLOW) { matched = true; break; } diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index 9801f38..9324159 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -76,31 +76,36 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, switch (m->type) { case ALL: - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case NETGROUP: if (netgr_matches(m->name, def_netgroup_tuple ? lhost : NULL, def_netgroup_tuple ? shost : NULL, pw->pw_name)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case USERGROUP: if (usergr_matches(m->name, pw->pw_name, pw)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case ALIAS: if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) { /* XXX */ - int rc = userlist_matches(parse_tree, pw, &a->members); - if (rc != UNSPEC) - matched = m->negated ? !rc : rc; + const int rc = userlist_matches(parse_tree, pw, &a->members); + if (rc != UNSPEC) { + if (m->negated) { + matched = rc == ALLOW ? DENY : ALLOW; + } else { + matched = rc; + } + } alias_put(a); break; } FALLTHROUGH; case WORD: if (userpw_matches(m->name, pw->pw_name, pw)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; } debug_return_int(matched); @@ -171,38 +176,43 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree, TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) { switch (m->type) { case ALL: - user_matched = !m->negated; + user_matched = m->negated ? DENY : ALLOW; break; case NETGROUP: if (netgr_matches(m->name, def_netgroup_tuple ? lhost : NULL, def_netgroup_tuple ? shost : NULL, runas_pw->pw_name)) - user_matched = !m->negated; + user_matched = m->negated ? DENY : ALLOW; break; case USERGROUP: if (usergr_matches(m->name, runas_pw->pw_name, runas_pw)) - user_matched = !m->negated; + user_matched = m->negated ? DENY : ALLOW; break; case ALIAS: a = alias_get(parse_tree, m->name, RUNASALIAS); if (a != NULL) { rc = runaslist_matches(parse_tree, &a->members, &empty, matching_user, NULL); - if (rc != UNSPEC) - user_matched = m->negated ? !rc : rc; + if (rc != UNSPEC) { + if (m->negated) { + user_matched = rc == ALLOW ? DENY : ALLOW; + } else { + user_matched = rc; + } + } alias_put(a); break; } FALLTHROUGH; case WORD: if (userpw_matches(m->name, runas_pw->pw_name, runas_pw)) - user_matched = !m->negated; + user_matched = m->negated ? DENY : ALLOW; break; case MYSELF: if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || strcmp(user_name, runas_pw->pw_name) == 0) - user_matched = !m->negated; + user_matched = m->negated ? DENY : ALLOW; break; } if (user_matched != UNSPEC) { @@ -226,22 +236,27 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree, TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) { switch (m->type) { case ALL: - group_matched = !m->negated; + group_matched = m->negated ? DENY : ALLOW; break; case ALIAS: a = alias_get(parse_tree, m->name, RUNASALIAS); if (a != NULL) { rc = runaslist_matches(parse_tree, &empty, &a->members, NULL, matching_group); - if (rc != UNSPEC) - group_matched = m->negated ? !rc : rc; + if (rc != UNSPEC) { + if (m->negated) { + group_matched = rc == ALLOW ? DENY : ALLOW; + } else { + group_matched = rc; + } + } alias_put(a); break; } FALLTHROUGH; case WORD: if (group_matches(m->name, runas_gr)) - group_matched = !m->negated; + group_matched = m->negated ? DENY : ALLOW; break; } if (group_matched != UNSPEC) { @@ -329,32 +344,37 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, switch (m->type) { case ALL: - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case NETGROUP: if (netgr_matches(m->name, lhost, shost, def_netgroup_tuple ? pw->pw_name : NULL)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case NTWKADDR: if (addr_matches(m->name)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case ALIAS: a = alias_get(parse_tree, m->name, HOSTALIAS); if (a != NULL) { /* XXX */ - int rc = hostlist_matches_int(parse_tree, pw, lhost, shost, - &a->members); - if (rc != UNSPEC) - matched = m->negated ? !rc : rc; + const int rc = hostlist_matches_int(parse_tree, pw, lhost, + shost, &a->members); + if (rc != UNSPEC) { + if (m->negated) { + matched = rc == ALLOW ? DENY : ALLOW; + } else { + matched = rc; + } + } alias_put(a); break; } FALLTHROUGH; case WORD: if (hostname_matches(shost, lhost, m->name)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; } debug_return_int(matched); @@ -399,14 +419,19 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m, case COMMAND: c = (struct sudo_command *)m->name; if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests)) - matched = !m->negated; + matched = m->negated ? DENY : ALLOW; break; case ALIAS: a = alias_get(parse_tree, m->name, CMNDALIAS); if (a != NULL) { rc = cmndlist_matches(parse_tree, &a->members, runchroot, info); - if (rc != UNSPEC) - matched = m->negated ? !rc : rc; + if (rc != UNSPEC) { + if (m->negated) { + matched = rc == ALLOW ? DENY : ALLOW; + } else { + matched = rc; + } + } alias_put(a); } break; -- 2.42.0.windows.2