Skip to content

Commit

Permalink
make authorized_keys environment="..." directives first-match-wins
Browse files Browse the repository at this point in the history
and more strictly limit their maximum number; prompted by OOM
reported by OSS-fuzz (35470).

feedback and ok dtucker@
  • Loading branch information
djmdjm committed Jul 23, 2021
1 parent 1ea674c commit 7224cb2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
35 changes: 24 additions & 11 deletions usr.bin/ssh/auth-options.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
Expand Down Expand Up @@ -321,6 +321,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;
Expand Down Expand Up @@ -394,7 +395,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;
}
Expand All @@ -408,23 +409,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)
Expand Down
7 changes: 5 additions & 2 deletions usr.bin/ssh/auth-options.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.h,v 1.30 2020/08/27 01:07:09 djm Exp $ */
/* $OpenBSD: auth-options.h,v 1.31 2021/07/23 03:57:20 djm Exp $ */

/*
* Copyright (c) 2018 Damien Miller <[email protected]>
Expand All @@ -23,7 +23,10 @@ struct passwd;
struct sshkey;

/* Maximum number of permitopen/permitlisten directives to accept */
#define SSH_AUTHOPT_PERMIT_MAX 4096
#define SSH_AUTHOPT_PERMIT_MAX 4096

/* Maximum number of environment directives to accept */
#define SSH_AUTHOPT_ENV_MAX 1024

/*
* sshauthopt represents key options parsed from authorized_keys or
Expand Down

0 comments on commit 7224cb2

Please sign in to comment.