Re: ksh / CVE-2019-14868
Attached is my patch to deal with this issue. It is mostly a copy and
paste of the code from the upstream patch, except the following changes
were required (and from the original code):
* The number call has been replaced with a strtonll call.
* The sh_isstate call has been changed to take only one parameter.
* The "Varsubscript = true;" line was removed.
I attempted to get tests working also, but these don't appear to be
getting called in the Debian tests. Instead I ran the tests manually by
hand, and they are produced expected values.
(stretch-i386-default)root@silverfish:/tmp/brian/tmpkaecyd6p/build/i386# SHLVL='7' ksh -c 'echo $SHLVL'
8
(stretch-i386-default)root@silverfish:/tmp/brian/tmpkaecyd6p/build/i386# SHLVL='013' ksh -c 'echo $SHLVL'
14
(stretch-i386-default)root@silverfish:/tmp/brian/tmpkaecyd6p/build/i386# SHLVL='2#11' ksh -c 'echo $SHLVL'
4
(stretch-i386-default)root@silverfish:/tmp/brian/tmpkaecyd6p/build/i386# SHLVL='16#B' ksh -c 'echo $SHLVL'
12
</build/i386# SHLVL='2#11+x[$(/bin/echo DANGER WILL ROBINSON >&2)0]' ksh -c 'echo $SHLVL'
1
diff -Nru ksh-93u+20120801/debian/changelog ksh-93u+20120801/debian/changelog
--- ksh-93u+20120801/debian/changelog 2017-05-31 19:57:56.000000000 +1000
+++ ksh-93u+20120801/debian/changelog 2020-07-16 07:53:51.000000000 +1000
@@ -1,3 +1,11 @@
+ksh (93u+20120801-3.1+deb9u1) stretch-security; urgency=high
+
+ * Non-maintainer upload by the LTS Team.
+ * Fix CVE-2019-14868: An attacker could use flaw to override or bypass
+ environment restrictions to execute shell commands.
+
+ -- Brian May <bam@debian.org> Thu, 16 Jul 2020 07:53:51 +1000
+
ksh (93u+20120801-3.1) unstable; urgency=medium
* Non-maintainer upload.
diff -Nru ksh-93u+20120801/debian/patches/CVE-2019-14868.patch ksh-93u+20120801/debian/patches/CVE-2019-14868.patch
--- ksh-93u+20120801/debian/patches/CVE-2019-14868.patch 1970-01-01 10:00:00.000000000 +1000
+++ ksh-93u+20120801/debian/patches/CVE-2019-14868.patch 2020-07-16 07:53:51.000000000 +1000
@@ -0,0 +1,83 @@
+--- a/src/cmd/ksh93/sh/arith.c
++++ b/src/cmd/ksh93/sh/arith.c
+@@ -511,23 +511,34 @@
+ Shell_t *shp = sh_getinterp();
+ register Sfdouble_t d;
+ char base=(shp->inarith?0:10), *last;
+- if(*str==0)
+- {
+- if(ptr)
+- *ptr = (char*)str;
+- return(0);
++ if(*str==0) {
++ d = 0.0;
++ last = (char *)str;
++ } else {
++ d = strtonll(str,&last,&base,-1);
++ if (*last && !shp->inarith && sh_isstate(SH_INIT)) {
++ // This call is to handle "base#value" literals if we're importing untrusted env vars.
++ base = 0;
++ d = strtonll(str,&last,&base,-1);
++ }
++ if (*last) {
++ if (sh_isstate(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);
++ }
++ if (!ptr && *last && mode > 0) {
++ errormsg(SH_DICT, ERROR_exit(1), e_lexbadchar, *last, str);
++ }
++ }
++ } else if (d == 0.0 && *str == '-') {
++ d = -0.0;
++ }
+ }
+- errno = 0;
+- d = strtonll(str,&last,&base,-1);
+- if(*last || errno)
+- {
+- if(!last || *last!='.' || last[1]!='.')
+- d = strval(shp,str,&last,arith,mode);
+- 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);
+--- a/src/cmd/ksh93/tests/subshell.sh
++++ b/src/cmd/ksh93/tests/subshell.sh
+@@ -617,4 +617,27 @@
+ fi
+ 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 ]] || err_exit "decimal int literal not recognized" "$expect" "$actual"
++
++expect=14
++actual=$(env SHLVL='013' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || err_exit "leading zeros int literal not recognized" "$expect" "$actual"
++
++expect=4
++actual=$(env SHLVL='2#11' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || err_exit "base#value int literal not recognized" "$expect" "$actual"
++
++expect=12
++actual=$(env SHLVL='16#B' $SHELL -c 'echo $SHLVL')
++[[ $actual == $expect ]] || err_exit "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 ]] || err_exit "expression allowed on env var import" "$expect" "$actual"
++
+ exit $((Errors<125?Errors:125))
diff -Nru ksh-93u+20120801/debian/patches/series ksh-93u+20120801/debian/patches/series
--- ksh-93u+20120801/debian/patches/series 2017-05-31 19:57:56.000000000 +1000
+++ ksh-93u+20120801/debian/patches/series 2020-07-16 07:52:34.000000000 +1000
@@ -5,3 +5,4 @@
spelling.patch
bug755486.patch
ed.patch
+CVE-2019-14868.patch
--
Brian May <bam@debian.org>
Reply to: