Do not evaluate arithmetic expressions from environment variables at startup

Resolves: #1790549
This commit is contained in:
Siteshwar Vashisht 2020-02-07 13:50:24 +01:00
parent 314ed9011d
commit 4d4d7c1d3b
2 changed files with 86 additions and 2 deletions

View File

@ -0,0 +1,78 @@
diff --git a/src/cmd/ksh93/sh/arith.c b/src/cmd/ksh93/sh/arith.c
--- a/src/cmd/ksh93/sh/arith.c
+++ b/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
--- a/src/cmd/ksh93/tests/subshell.sh
+++ b/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"

View File

@ -3,7 +3,7 @@ Summary: The Original ATT Korn Shell
URL: http://www.kornshell.com/ URL: http://www.kornshell.com/
License: EPL License: EPL
Version: 2020.0.0 Version: 2020.0.0
Release: 2%{?dist} Release: 3%{?dist}
# We are upgrading from ksh-20120801-250, so set epoch. # We are upgrading from ksh-20120801-250, so set epoch.
Epoch: 1 Epoch: 1
Source0: https://github.com/att/ast/releases/download/%{version}/%{name}-%{version}.tar.gz Source0: https://github.com/att/ast/releases/download/%{version}/%{name}-%{version}.tar.gz
@ -11,6 +11,8 @@ Source1: kshcomp.conf
Source2: kshrc.rhs Source2: kshrc.rhs
Source3: dotkshrc Source3: dotkshrc
Patch1: ksh-2020.0.0-cve-2019-14868.patch
Provides: /bin/ksh Provides: /bin/ksh
BuildRequires: meson BuildRequires: meson
@ -32,7 +34,7 @@ KornShell is a shell programming language, which is upward compatible
with "sh" (the Bourne Shell). with "sh" (the Bourne Shell).
%prep %prep
%autosetup -n %{name}-%{version} %autosetup -n %{name}-%{version} -p1
%build %build
%meson -Dbuild-api-tests=false %meson -Dbuild-api-tests=false
@ -108,6 +110,10 @@ done
%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf %config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf
%changelog %changelog
* Fri Feb 07 2020 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-3
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #1790549
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:2020.0.0-2 * Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:2020.0.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild