summaryrefslogtreecommitdiff
path: root/auth-options.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2021-07-23 03:57:20 +0000
committerDamien Miller <djm@mindrot.org>2021-07-23 14:07:19 +1000
commite3957e21ffdc119d6d04c0b1686f8e2fe052f5ea (patch)
treec2bcc5fc02be59f914ea4f0e04981fc0162c2613 /auth-options.c
parentd0bb1ce731762c55acb95817df4d5fab526c7ecd (diff)
downloadopenssh-git-e3957e21ffdc119d6d04c0b1686f8e2fe052f5ea.tar.gz
upstream: make authorized_keys environment="..." directives
first-match-wins and more strictly limit their maximum number; prompted by OOM reported by OSS-fuzz (35470). feedback and ok dtucker@ OpenBSD-Commit-ID: 01f63fc10dcd995e7aed9c378ad879161af83121
Diffstat (limited to 'auth-options.c')
-rw-r--r--auth-options.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/auth-options.c b/auth-options.c
index f68c629d..aa5da78a 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.95 2021/04/03 06:18:40 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.96 2021/07/23 03:57:20 djm Exp $ */
/*
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
*
@@ -324,6 +324,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
struct sshauthopt *ret = NULL;
const char *errstr = "unknown error";
uint64_t valid_before;
+ size_t i, l;
if (errstrp != NULL)
*errstrp = NULL;
@@ -397,7 +398,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
valid_before < ret->valid_before)
ret->valid_before = valid_before;
} else if (opt_match(&opts, "environment")) {
- if (ret->nenv > INT_MAX) {
+ if (ret->nenv > SSH_AUTHOPT_ENV_MAX) {
errstr = "too many environment strings";
goto fail;
}
@@ -411,23 +412,35 @@ sshauthopt_parse(const char *opts, const char **errstrp)
}
if ((cp = strdup(opt)) == NULL)
goto alloc_fail;
- cp[tmp - opt] = '\0'; /* truncate at '=' */
+ l = (size_t)(tmp - opt);
+ cp[l] = '\0'; /* truncate at '=' */
if (!valid_env_name(cp)) {
free(cp);
free(opt);
errstr = "invalid environment string";
goto fail;
}
+ /* Check for duplicates; XXX O(n*log(n)) */
+ for (i = 0; i < ret->nenv; i++) {
+ if (strncmp(ret->env[i], cp, l) == 0 &&
+ ret->env[i][l] == '=')
+ break;
+ }
free(cp);
- /* Append it. */
- oarray = ret->env;
- if ((ret->env = recallocarray(ret->env, ret->nenv,
- ret->nenv + 1, sizeof(*ret->env))) == NULL) {
- free(opt);
- ret->env = oarray; /* put it back for cleanup */
- goto alloc_fail;
+ /* First match wins */
+ if (i >= ret->nenv) {
+ /* Append it. */
+ oarray = ret->env;
+ if ((ret->env = recallocarray(ret->env,
+ ret->nenv, ret->nenv + 1,
+ sizeof(*ret->env))) == NULL) {
+ free(opt);
+ /* put it back for cleanup */
+ ret->env = oarray;
+ goto alloc_fail;
+ }
+ ret->env[ret->nenv++] = opt;
}
- ret->env[ret->nenv++] = opt;
} else if (opt_match(&opts, "permitopen")) {
if (handle_permit(&opts, 0, &ret->permitopen,
&ret->npermitopen, &errstr) != 0)