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 <b...@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 <b...@debian.org>

Reply via email to