aboutsummaryrefslogtreecommitdiff
path: root/shells
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2020-02-07 19:40:12 +0000
committerCy Schubert <cy@FreeBSD.org>2020-02-07 19:40:12 +0000
commit4d7701aa237ef1270512bf5ad0211f359e5fae58 (patch)
treea0bc0f33645dab4630178e7ebf2324f40db79389 /shells
parentf90869f79eb6b6e23b746912413945caaf3e0e44 (diff)
downloadports-4d7701aa237ef1270512bf5ad0211f359e5fae58.tar.gz
ports-4d7701aa237ef1270512bf5ad0211f359e5fae58.zip
Add patch missed from r525497.
Notes
Notes: svn path=/head/; revision=525502
Diffstat (limited to 'shells')
-rw-r--r--shells/ksh93/files/patch-ksh-2020.0.0-cve-2019-14868.patch78
1 files changed, 78 insertions, 0 deletions
diff --git a/shells/ksh93/files/patch-ksh-2020.0.0-cve-2019-14868.patch b/shells/ksh93/files/patch-ksh-2020.0.0-cve-2019-14868.patch
new file mode 100644
index 000000000000..c44111ffea5e
--- /dev/null
+++ b/shells/ksh93/files/patch-ksh-2020.0.0-cve-2019-14868.patch
@@ -0,0 +1,78 @@
+diff --git a/src/cmd/ksh93/sh/arith.c b/src/cmd/ksh93/sh/arith.c
+--- src/cmd/ksh93/sh/arith.c
++++ src/cmd/ksh93/sh/arith.c
+@@ -567,19 +567,32 @@ Sfdouble_t sh_strnum(Shell_t *shp, const char *str, char **ptr, int mode) {
+ char *last;
+
+ if (*str == 0) {
+- if (ptr) *ptr = (char *)str;
+- return 0;
+- }
+- errno = 0;
+- d = number(str, &last, shp->inarith ? 0 : 10, NULL);
+- if (*last) {
+- if (*last != '.' || last[1] != '.') {
+- d = strval(shp, str, &last, arith, mode);
+- Varsubscript = true;
++ d = 0.0;
++ last = (char *)str;
++ } else {
++ d = number(str, &last, shp->inarith ? 0 : 10, NULL);
++ if (*last && !shp->inarith && sh_isstate(shp, SH_INIT)) {
++ // This call is to handle "base#value" literals if we're importing untrusted env vars.
++ d = number(str, &last, 0, NULL);
++ }
++ if (*last) {
++ if (sh_isstate(shp, SH_INIT)) {
++ // Initializing means importing untrusted env vars. Since the string does not appear
++ // to be a recognized numeric literal give up. We can't safely call strval() since
++ // that allows arbitrary expressions which would create a security vulnerability.
++ d = 0.0;
++ } else {
++ if (*last != '.' || last[1] != '.') {
++ d = strval(shp, str, &last, arith, mode);
++ Varsubscript = true;
++ }
++ if (!ptr && *last && mode > 0) {
++ errormsg(SH_DICT, ERROR_exit(1), e_lexbadchar, *last, str);
++ }
++ }
++ } else if (d == 0.0 && *str == '-') {
++ d = -0.0;
+ }
+- if (!ptr && *last && mode > 0) errormsg(SH_DICT, ERROR_exit(1), e_lexbadchar, *last, str);
+- } else if (!d && *str == '-') {
+- d = -0.0;
+ }
+ if (ptr) *ptr = last;
+ return d;
+diff --git a/src/cmd/ksh93/tests/subshell.sh b/src/cmd/ksh93/tests/subshell.sh
+--- src/cmd/ksh93/tests/subshell.sh
++++ src/cmd/ksh93/tests/subshell.sh
+@@ -856,3 +856,26 @@ for exp in 65535 65536
+ do got=$($SHELL -c 'x=$(printf "%.*c" '$exp' x); print ${#x}' 2>&1)
+ [[ $got == $exp ]] || log_error "large command substitution failed" "$exp" "$got"
+ done
++
++# ==========
++# Verify that importing untrusted env vars does not allow evaluating arbitrary expressions but does
++# recognize all integer literals recognized by ksh.
++expect=8
++actual=$(env SHLVL='7' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || log_error "decimal int literal not recognized" "$expect" "$actual"
++
++expect=14
++actual=$(env SHLVL='013' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || log_error "leading zeros int literal not recognized" "$expect" "$actual"
++
++expect=4
++actual=$(env SHLVL='2#11' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || log_error "base#value int literal not recognized" "$expect" "$actual"
++
++expect=12
++actual=$(env SHLVL='16#B' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || log_error "base#value int literal not recognized" "$expect" "$actual"
++
++expect=1
++actual=$(env SHLVL="2#11+x[\$($bin_echo DANGER WILL ROBINSON >&2)0]" $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || log_error "expression allowed on env var import" "$expect" "$actual"