[PATCH] ssh: reject "all" combined with other Match criteria

762233433 at qq.com 762233433 at qq.com
Tue Nov 3 18:26:51 AEDT 2026


From: xuehaolin <xuehaolin at uniontech.com>

match_cfg_line() in readconf.c checks whether the "all" keyword is
combined with other criteria with "attributes > 1", but increments
attributes only after that check.  "all" therefore observes the number
of preceding criteria, so "Match user foo all" passes the check and is
silently accepted.

sshd's servconf.c increments the counter before the check and rejects
the same configuration, so the client and server disagree about which
configurations are valid.

Move the increment ahead of the check to match servconf.c, and add
regression test coverage for both the standalone "Match all" case and
the combined "Match user foo all" case.
---
 readconf.c             |  2 +-
 regress/sshcfgparse.sh | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/readconf.c b/readconf.c
index 3c21bcb..5c6d3ac 100644
--- a/readconf.c
+++ b/readconf.c
@@ -777,6 +777,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp,
 		this_result = 1;
 		if ((negate = (attrib[0] == '!')))
 			attrib++;
+		attributes++;
 		/* Criterion "all" has no argument and must appear alone */
 		if (strcasecmp(attrib, "all") == 0) {
 			if (attributes > 1 ||
@@ -794,7 +795,6 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp,
 				result = negate ? 0 : 1;
 			goto out;
 		}
-		attributes++;
 		/* criteria "final" and "canonical" have no argument */
 		if (strcasecmp(attrib, "canonical") == 0 ||
 		    strcasecmp(attrib, "final") == 0) {
diff --git a/regress/sshcfgparse.sh b/regress/sshcfgparse.sh
index 784e841..7cfd74e 100644
--- a/regress/sshcfgparse.sh
+++ b/regress/sshcfgparse.sh
@@ -117,5 +117,20 @@ EOD
 f=`${SSH} -GF $OBJ/ssh_config.0 host true | awk '/^stdinnull /{print$2}'`
 expect_result_present "$f" "yes"
 
+# "all" must appear alone in a Match block
+verbose "Match all"
+cat >$OBJ/ssh_config.0 <<EOD
+Match all
+	Compression yes
+EOD
+${SSH} -GF $OBJ/ssh_config.0 host >/dev/null 2>&1 || \
+	fail "standalone Match all rejected"
+cat >$OBJ/ssh_config.0 <<EOD
+Match user foo all
+	Compression yes
+EOD
+${SSH} -GF $OBJ/ssh_config.0 host >/dev/null 2>&1 && \
+	fail "Match combined with all accepted"
+
 # cleanup
 rm -f $OBJ/ssh_config.[012]
-- 
2.43.0



More information about the openssh-unix-dev mailing list