17817727 ksh93: Right shift arithmetic substitution error for shifts of 64 bits or more
17699248 ksh93 double associative array handling bugs
17777549 "kill %%" with no background jobs , coredumps
18229654 ksh93 read not reentrant in alarm context dumps core
19907453 Session drop can cause ksh93 to become a fork bomb
22461939 ksh93 20120801 version core dumps with Asian characters input
22550551 ksh dumps core in tc_ibtools testsuite run during OFUV testing
22561374 export in a subshell visible in another subshell
22964126 ksh93 memory leak:unset is not properly freeing members of an associative array
22964338 ksh93 appears to send SIGHUP to unrelated processes on occasion
22964358 ksh93: -u option does not treat unset parameter as an error
--- a/components/ksh93/Makefile Thu May 26 22:52:21 2016 -0700
+++ b/components/ksh93/Makefile Thu May 26 22:52:21 2016 -0700
@@ -81,7 +81,10 @@
Bug15993811.patch 21547336.patch \
17777549.patch 17699248.patch \
17817727.patch 18229654.patch \
- 19907453.patch
+ 19907453.patch 22461939.patch \
+ 22550551.patch 22561374.patch \
+ 22964126.patch 22964338.patch \
+ 22964358.patch
# Fixup HOSTTYPE to match uname output and bits
HOSTTYPE32=sol11.$(shell uname -p)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/17699248.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,14 @@
+This fix is from the community, details in the following location.
+http://lists.research.att.com/pipermail/ast-developers/2013q4/003716.html
+---
+--- a/src/cmd/ksh93/sh/array.c 2013-11-15 12:39:50.632526510 +0100
++++ b/src/cmd/ksh93/sh/array.c 2013-11-15 12:45:53.420869610 +0100
+@@ -963,7 +963,7 @@
+ ap->nelem = nelem;
+ ap->fun = fun;
+ nv_onattr(np,NV_ARRAY);
+- if(fp || value)
++ if(fp || (value && value!=Empty))
+ {
+ nv_putsub(np, "0", ARRAY_ADD);
+ if(value)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/17777549.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,21 @@
+This issue has been fixed in community version: 2013-10-10
+---
+--- a/src/cmd/ksh93/sh/jobs.c 2013-11-12 10:32:35.378209600 -0800
++++ b/src/cmd/ksh93/sh/jobs.c 2013-11-12 10:35:10.458987800 -0800
+@@ -1100,7 +1100,7 @@
+
+ int job_kill(register struct process *pw,register int sig)
+ {
+- Shell_t *shp = pw->p_shp;
++ Shell_t *shp;
+ register pid_t pid;
+ register int r;
+ const char *msg;
+@@ -1113,6 +1113,7 @@
+ errno = ECHILD;
+ if(pw==0)
+ goto error;
++ shp = pw->p_shp;
+ pid = pw->p_pid;
+ #if SHOPT_COSHELL
+ if(pw->p_cojob)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/17817727.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,25 @@
+This fix is from the community, details in the following location.
+http://lists.research.att.com/pipermail/ast-users/2013q4/004481.html
+---
+--- a/src/cmd/ksh93/sh/streval.c 2014-01-22 10:39:11.075964500 +0100
++++ b/src/cmd/ksh93/sh/streval.c 2014-01-22 13:21:35.999184260 +0100
+@@ -366,13 +366,17 @@
+ num = (Sflong_t)(sp[-1]) / (Sflong_t)(num);
+ break;
+ case A_LSHIFT:
+- if(tp[-1]==2)
++ if((long)num >= CHAR_BIT*sizeof(Sfulong_t))
++ num = 0;
++ else if(tp[-1]==2)
+ num = U2F((Sfulong_t)(sp[-1]) << (long)(num));
+ else
+ num = (Sflong_t)(sp[-1]) << (long)(num);
+ break;
+ case A_RSHIFT:
+- if(tp[-1]==2)
++ if((long)num >= CHAR_BIT*sizeof(Sfulong_t))
++ num = 0;
++ else if(tp[-1]==2)
+ num = U2F((Sfulong_t)(sp[-1]) >> (long)(num));
+ else
+ num = (Sflong_t)(sp[-1]) >> (long)(num);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/18229654.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,28 @@
+This fix is from the community, details in the following location.
+http://lists.research.att.com/pipermail/ast-developers/2014q1/003846.html
+---
+--- a/src/cmd/ksh93/bltins/alarm.c_org Tue Mar 25 13:42:56 2014
++++ b/src/cmd/ksh93/bltins/alarm.c Tue Mar 25 13:43:07 2014
+@@ -122,7 +122,7 @@
+ tp->timeout = 0;
+ tp->flags |= L_FLAG;
+ tp->sh->sigflag[SIGALRM] |= SH_SIGALRM;
+- if(sh_isstate(SH_TTYWAIT))
++ if(sh_isstate(SH_TTYWAIT) && !tp->sh->bltinfun)
+ sh_timetraps(tp->sh);
+ }
+
+--- a/src/cmd/ksh93/sh/xec.c_org Tue Mar 25 13:46:48 2014
++++ b/src/cmd/ksh93/sh/xec.c Tue Mar 25 13:48:18 2014
+@@ -2720,6 +2720,11 @@
+ break;
+ }
+ }
++ if(shp->trapnote&SH_SIGALRM)
++ {
++ shp->trapnote &= ~SH_SIGALRM;
++ sh_timetraps(shp);
++ }
+ if(shp->trapnote || (shp->exitval && sh_isstate(SH_ERREXIT)) &&
+ t && echeck)
+ sh_chktrap(shp);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/19907453.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,14 @@
+This fix is from the community, details in the following location.
+http://lists.research.att.com/pipermail/ast-developers/2013q1/002323.html
+
+--- INIT.2011-02-08.old/src/cmd/ksh93/sh/fault.c 2014-10-29 12:41:23.239718243 -0700
++++ INIT.2011-02-08/src/cmd/ksh93/sh/fault.c 2014-10-29 14:03:09.196910448 -0700
+@@ -519,7 +519,7 @@ void sh_exit(register int xno)
+ if(pp && pp->mode>1)
+ cursig = -1;
+ #ifdef SIGTSTP
+- if(shp->trapnote&SH_SIGTSTP)
++ if(shp->trapnote&SH_SIGTSTP && job.jobcontrol)
+ {
+ /* ^Z detected by the shell */
+ shp->trapnote = 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22461939.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,48 @@
+This fix has been developed inhouse. Patch has been submitted upstream but
+has not been accepted yet. The details can be found at
+https://github.com/att/ast/issues/6
+--- INIT.2012-08-01.old/src/cmd/ksh93/edit/emacs.c 2016-01-18 03:52:58.380801240 -0800
++++ INIT.2012-08-01/src/cmd/ksh93/edit/emacs.c 2016-02-05 01:39:08.350312914 -0800
+@@ -90,6 +90,7 @@
+ static int print(int);
+ static int _isword(int);
+ # define isword(c) _isword(out[c])
++# define digit(c) ((c&~STRIP)==0 && isdigit(c))
+
+ #else
+ # define gencpy(a,b) strcpy((char*)(a),(char*)(b))
+@@ -97,6 +98,7 @@
+ # define genlen(str) strlen(str)
+ # define print(c) isprint(c)
+ # define isword(c) (isalnum(out[c]) || (out[c]=='_'))
++# define digit(c) isdigit(c)
+ #endif /*SHOPT_MULTIBYTE */
+
+ typedef struct _emacs_
+@@ -317,7 +319,7 @@
+ count = 1;
+ adjust = -1;
+ i = cur;
+- if(c!='\t' && c!=ESC && !isdigit(c))
++ if(c!='\t' && c!=ESC && !digit(c))
+ ep->ed->e_tabcount = 0;
+ switch(c)
+ {
+@@ -775,7 +777,7 @@
+ int digit,ch;
+ digit = 0;
+ value = 0;
+- while ((i=ed_getchar(ep->ed,0)),isdigit(i))
++ while ((i=ed_getchar(ep->ed,0)),digit(i))
+ {
+ value *= 10;
+ value += (i - '0');
+@@ -1013,7 +1015,7 @@
+ {
+ i=ed_getchar(ep->ed,0);
+ ed_ungetchar(ep->ed,i);
+- if(isdigit(i))
++ if(digit(i))
+ ed_ungetchar(ep->ed,ESC);
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22550551.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,120 @@
+This issue has been fixed upstream in the 2016-01-10-beta version.
+--- INIT.2012-08-01.old/src/cmd/ksh93/sh/jobs.c 2015-10-30 05:05:17.556367591 -0700
++++ INIT.2012-08-01.new/src/cmd/ksh93/sh/jobs.c 2016-02-23 04:23:52.229101513 -0800
+@@ -58,6 +58,7 @@
+ struct jobsave *next;
+ pid_t pid;
+ unsigned short exitval;
++ unsigned short env;
+ };
+
+ static struct jobsave *job_savelist;
+@@ -133,7 +134,7 @@
+ #define P_BG 01000
+ #endif /* SHOPT_BGX */
+
+-static int job_chksave(pid_t);
++static int job_chksave(pid_t,long);
+ static struct process *job_bypid(pid_t);
+ static struct process *job_byjid(int);
+ static char *job_sigmsg(int);
+@@ -233,9 +234,9 @@
+ static struct jobsave *jobsave_create(pid_t pid)
+ {
+ register struct jobsave *jp = job_savelist;
+- job_chksave(pid);
++ job_chksave(pid,-1);
+ if(++bck.count > shgd->lim.child_max)
+- job_chksave(0);
++ job_chksave(0,-1);
+ if(jp)
+ {
+ njob_savelist--;
+@@ -425,7 +426,7 @@
+ if(pid<=0)
+ break;
+ if(wstat==0)
+- job_chksave(pid);
++ job_chksave(pid,-1);
+ flags |= WNOHANG;
+ job.waitsafe++;
+ jp = 0;
+@@ -1393,7 +1394,7 @@
+ else
+ pw->p_name = -1;
+ #endif /* JOBS */
+- if ((val = job_chksave(pid))>=0 && !jobfork)
++ if ((val = job_chksave(pid,pw->p_env))>=0 && !jobfork)
+ {
+ pw->p_exit = val;
+ if(pw->p_exit==SH_STOPSIG)
+@@ -1515,7 +1516,7 @@
+ if(!(pw=job_bypid(pid)))
+ {
+ /* check to see whether job status has been saved */
+- if((shp->exitval = job_chksave(pid)) < 0)
++ if((shp->exitval = job_chksave(pid,shp->curenv)) < 0)
+ shp->exitval = ERROR_NOENT;
+ exitset();
+ job_unlock();
+@@ -1937,7 +1938,7 @@
+ * if pid==0, then oldest saved process is deleted
+ * If pid is not found a -1 is returned.
+ */
+-static int job_chksave(register pid_t pid)
++static int job_chksave(register pid_t pid, long env)
+ {
+ register struct jobsave *jp = bck.list, *jpold=0;
+ register int r= -1;
+@@ -1957,9 +1958,10 @@
+ {
+ count = bp->count;
+ jp = bp->list;
++ jpold = 0;
+ goto again;
+ }
+- if(jp)
++ if(jp && (env<0 || jp->env==env))
+ {
+ r = 0;
+ if(pid)
+@@ -1996,15 +1998,18 @@
+
+ void job_subrestore(void* ptr)
+ {
+- register struct jobsave *jp;
++ register struct jobsave *jp,*jpnext;
+ register struct back_save *bp = (struct back_save*)ptr;
+ register struct process *pw, *px, *pwnext;
+ struct jobsave *end=NULL;
++ int i=0;
+ job_lock();
+- for(jp=bck.list; jp; jp=jp->next)
++ for(jp=bck.list; jp; jp=jpnext,i++)
+ {
+- if (!jp->next)
++ if (!(jpnext=jp->next) || jp==jpnext)
+ end = jp;
++ if(i>=shgd->lim.child_max)
++ break;
+ }
+ if(end)
+ end->next = bp->list;
+@@ -2013,7 +2018,7 @@
+ bck.count += bp->count;
+ bck.prev = bp->prev;
+ while(bck.count > shgd->lim.child_max)
+- job_chksave(0);
++ job_chksave(0,-1);
+ for(pw=job.pwlist; pw; pw=pwnext)
+ {
+ pwnext = pw->p_nxtjob;
+@@ -2051,7 +2056,7 @@
+ job.in_critical = 0;
+ break;
+ default:
+- job_chksave(parent);
++ job_chksave(parent,-1);
+ jobfork=0;
+ job_unlock();
+ break;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22561374.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,15 @@
+This fix has been developed inhouse. Patch has been submitted upstream but
+has not been accepted yet. The details can be found at
+https://github.com/att/ast/issues/7
+--- INIT.2012-08-01.old/src/cmd/ksh93/sh/subshell.c 2016-03-01 04:01:06.513890578 -0800
++++ INIT.2012-08-01/src/cmd/ksh93/shsubshell.c 2016-03-01 04:02:43.617872391 -0800
+@@ -260,9 +260,6 @@
+ shp = sp->shp;
+ dp = shp->var_tree;
+
+- /* don't bother to save if in newer scope */
+- if(sp->var!=shp->var_tree && sp->var!=shp->var_base && shp->last_root==shp->var_tree)
+- return(np);
+ if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
+ {
+ shp->last_root = ap->table;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22964126.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,22 @@
+This fix is from the community, details in the following location.
+https://www.mail-archive.com/[email protected]/msg01017.html
+--- INIT.2011-02-08.old/src/cmd/ksh93/sh/name.c 2015-04-14 13:17:18.598612500 -0700
++++ INIT.2011-02-08/src/cmd/ksh93/sh/name.c 2015-04-14 13:28:33.128198600 -0700
+@@ -1301,7 +1301,17 @@
+ if(dtdelete(root,np))
+ {
+ if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
++ {
++ Namarr_t *ap;
++ if(nv_isarray(np) && np->nvfun &&
++ (ap=nv_arrayptr(np)) && array_assoc(ap)) {
++ while(nv_associative(np,0,NV_ANEXT))
++ nv_associative(np, 0, NV_ADELETE);
++ nv_associative(np, 0, NV_AFREE);
++ free((void*)np->nvfun);
++ }
+ free((void*)np);
++ }
+ }
+ #if 0
+ else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22964338.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,89 @@
+This fix has been developed inhouse and has been submitted to the community
+but not accepted yet.
+Details of submission can be found at
+https://github.com/att/ast/pull/1
+--- INIT.2011-02-08.old/src/cmd/ksh93/include/jobs.h 2015-03-03 00:21:58.242706370 -0800
++++ INIT.2011-02-08/src/cmd/ksh93/include/jobs.h 2015-03-03 00:40:48.894575330 -0800
+@@ -203,6 +203,7 @@
+ extern int job_close(Shell_t*);
+ extern int job_list(struct process*,int);
+ extern int job_terminate(struct process*,int);
++ extern int job_hup(struct process *, int);
+ extern int job_switch(struct process*,int);
+ extern void job_fork(pid_t);
+ extern int job_reap(int);
+--- INIT.2011-02-08.old/src/cmd/ksh93/sh/fault.c 2015-03-03 00:21:58.214056350 -0800
++++ INIT.2011-02-08/src/cmd/ksh93/sh/fault.c 2015-03-03 00:40:44.367029380 -0800
+@@ -635,7 +635,7 @@
+ #endif
+ #ifdef JOBS
+ if((sh_isoption(SH_INTERACTIVE) && shp->login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
+- job_walk(sfstderr,job_terminate,SIGHUP,NIL(char**));
++ job_walk(sfstderr, job_hup, SIGHUP, NIL(char**));
+ #endif /* JOBS */
+ job_close(shp);
+ if(nv_search("VMTRACE", shp->var_tree,0))
+--- INIT.2011-02-08.old/src/cmd/ksh93/sh/jobs.c 2015-03-03 00:22:16.741450850 -0800
++++ INIT.2011-02-08/src/cmd/ksh93/sh/jobs.c 2015-03-03 00:44:48.323265420 -0800
+@@ -1211,6 +1211,61 @@
+ }
+
+ /*
++ * Similar to job_kill, but dedicated to SIGHUP handling when session is
++ * being disconnected.
++ */
++int
++job_hup(struct process *pw, int sig)
++{
++ struct process *px;
++ pid_t pid;
++ int r;
++
++ if (pw->p_pgrp == 0 || (pw->p_flag & P_DISOWN))
++ return (0);
++
++#if SHOPT_COSHELL
++ if(pw->p_cojob) {
++ job_lock();
++ r = cokill(pw->p_cojob->coshell,pw->p_cojob,sig);
++ job_unlock();
++ return (r);
++ }
++#endif /* SHOPT_COSHELL */
++
++ job_lock();
++ if (pw->p_pgrp != 0) {
++ int palive = 0;
++
++ for (px = pw; px != NULL; px = px->p_nxtproc) {
++ if ((px->p_flag & P_DONE) == 0) {
++ palive = 1;
++ break;
++ }
++ }
++ /*
++ * If all the processes have been dead, there is no guarantee
++ * that the p_pgrp is still the valid process group that we
++ * made, ie pid may have been recycled and same p_pgrp may
++ * have been assigned to unrelated processes.
++ */
++ if (palive) {
++ if (killpg(pw->p_pgrp, SIGHUP) >= 0)
++ job_unstop(pw);
++ }
++ }
++ for (; pw != NULL && pw->p_pgrp == 0; pw = pw->p_nxtproc) {
++ if (pw->p_flag & P_DONE)
++ continue;
++ if (kill(pw->p_pid, SIGHUP) >= 0)
++ (void) kill(pw->p_pid, SIGCONT);
++ pw = pw->p_nxtproc;
++ }
++ job_unlock();
++ return(0);
++}
++
++/*
+ * Get process structure from first letters of jobname
+ *
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ksh93/patches/22964358.patch Thu May 26 22:52:21 2016 -0700
@@ -0,0 +1,20 @@
+This fix was developed inhouse on top of the ksh93 alpha version(2013-10-10-alpha).
+This has been submitted to the community but not been accepted yet.
+Details can be found at
+https://github.com/att/ast/issues/5
+--- INIT.2011-02-08.old/src/cmd/ksh93/sh/macro.c 2015-05-04 13:33:02.298225000 -0700
++++ INIT.2011-02-08/src/cmd/ksh93/sh/macro.c 2015-06-03 13:20:45.726236100 -0700
+@@ -1195,6 +1195,13 @@
+ }
+ else
+ v = 0;
++ if(!v && sh_isoption(SH_NOUNSET))
++ {
++ d=fcget();
++ fcseek(-1);
++ if(d=='\0' || !strchr(":+-?=",d))
++ errormsg(SH_DICT,ERROR_exit(1),e_notset,ltos(c));
++ }
+ break;
+ case S_ALP:
+ if(c=='.' && type==0)