17817727 ksh93: Right shift arithmetic substitution error for shifts of 64 bits or more s11u3-sru
authorLijo George<lijo.x.george@oracle.com>
Thu, 26 May 2016 22:52:21 -0700
branchs11u3-sru
changeset 6075 3d0b04972053
parent 6074 4a3952ad8c2a
child 6076 0d5715bee554
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
components/ksh93/Makefile
components/ksh93/patches/17699248.patch
components/ksh93/patches/17777549.patch
components/ksh93/patches/17817727.patch
components/ksh93/patches/18229654.patch
components/ksh93/patches/19907453.patch
components/ksh93/patches/22461939.patch
components/ksh93/patches/22550551.patch
components/ksh93/patches/22561374.patch
components/ksh93/patches/22964126.patch
components/ksh93/patches/22964338.patch
components/ksh93/patches/22964358.patch
--- 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)