components/ksh93/patches/100-CR6964621.patch
author Lijo George<lijo.x.george@oracle.com>
Sun, 10 May 2015 11:59:46 -0700
changeset 4268 d723f8ed85fe
parent 4196 d697072a92f5
child 4305 90493abe0c5c
permissions -rw-r--r--
PSARC/2014/162 ksh93 update to 2012-08-01 17533968 ksh93 uprev to latest community version 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 18119738 ksh93 crashes in sfio area 18229654 ksh93 read not reentrant in alarm context dumps core 16169978 ksh93 memory corruption with redirection 18302723 ksh93 segv in sh_setmatch 16507675 external command in double-nested here-document hangs ksh93 18920300 remove pkglint Warnings in ksh93 build 18355790 /usr/bin/sh and /usr/sbin/sh should point to /usr/bin/ksh93 19907453 Session drop can cause ksh93 to become a fork bomb 18426052 SPARC /usr/bin/ksh is not an XPG6 executable 20808157 attpackagemake.mk test target needs the same environment as the build 20948390 ksh93 should have some master test results to compare against 20948350 attpackagemake.mk tested-and-compared target has mis-matched parentheses

# This patch has been developed inhouse. This fixes a Solaris specific
# issue and has not been submitted to the community.
--- INIT.2012-08-01.old/src/cmd/ksh93/include/io.h	2015-02-24 13:25:19.331558350 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/include/io.h	2015-03-04 13:27:49.205782578 -0800
@@ -23,6 +23,9 @@
  *	David Korn
  *
  */
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
 
 #include	<ast.h>
 #include	<sfio.h>
@@ -87,6 +90,12 @@ extern int	sh_devtofd(const char*);
 extern int	sh_isdevfd(const char*);
 extern int	sh_source(Shell_t*, Sfio_t*, const char*);
 
+extern int	VALIDATE_FD(Shell_t *, int);
+
+#define	VALIDATE_FD(shp, fd) \
+	(((fd) >= (shp)->gd->lim.open_max) ? sh_iovalidfd(shp, fd) : 1)
+
+
 /* the following are readonly */
 extern const char	e_pexists[];
 extern const char	e_query[];
@@ -126,4 +135,5 @@ extern const char	e_bash_profile[];
 extern const char	e_stdprompt[];
 extern const char	e_supprompt[];
 extern const char	e_ambiguous[];
+
 #endif /* KSHELL */
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/io.c	2015-02-24 13:25:19.362427732 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/io.c	2015-03-04 14:04:54.981280201 -0800
@@ -605,8 +605,10 @@ static void io_preserve(Shell_t* shp, re
 		((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
 		errormsg(SH_DICT,ERROR_system(1),e_toomany);
 	}
-	if(f2 >= shp->gd->lim.open_max)
-		sh_iovalidfd(shp,f2);
+
+	VALIDATE_FD(shp, fd);
+	VALIDATE_FD(shp, f2);
+
 	if(shp->fdptrs[fd]=shp->fdptrs[f2])
 	{
 		if(f2==job.fd)
@@ -632,7 +634,12 @@ static void io_preserve(Shell_t* shp, re
  */
 int sh_iorenumber(Shell_t *shp, register int f1,register int f2)
 {
-	register Sfio_t *sp = shp->sftable[f2];
+	register Sfio_t *sp;
+
+	VALIDATE_FD(shp, f1);
+	VALIDATE_FD(shp, f2);
+
+	sp = shp->sftable[f2];
 	if(f1!=f2)
 	{
 		/* see whether file descriptor is in use */
@@ -672,8 +679,7 @@ int sh_iorenumber(Shell_t *shp, register
 		if(f2<=2)
 			sfset(sp,SF_SHARE|SF_PUBLIC,1);
 	}
-	if(f2>=shp->gd->lim.open_max)
-		sh_iovalidfd(shp,f2);
+	VALIDATE_FD(shp, f2);
 	return(f2);
 }
 
@@ -687,8 +693,9 @@ int sh_close(register int fd)
 	register int r = 0;
 	if(fd<0)
 		return(-1);
-	if(fd >= shp->gd->lim.open_max)
-		sh_iovalidfd(shp,fd);
+
+	VALIDATE_FD(shp, fd);
+
 	if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0)
 	{
 		int err=errno;
@@ -846,8 +853,7 @@ int sh_open(register const char *path, i
 		mode = (IOREAD|IOWRITE);
 	else
 		mode = IOREAD;
-	if(fd >= shp->gd->lim.open_max)
-		sh_iovalidfd(shp,fd);
+	VALIDATE_FD(shp, fd);
 	shp->fdstatus[fd] = mode;
 	return(fd);
 }
@@ -876,6 +882,8 @@ int sh_iomovefd(register int fdold)
 	if(fdold<0 || fdold>2)
 		return(fdold);
 	fdnew = sh_iomovefd(dup(fdold));
+	VALIDATE_FD(shp, fdold);
+	VALIDATE_FD(shp, fdnew);
 	shp->fdstatus[fdnew] = (shp->fdstatus[fdold]&~IOCLEX);
 	close(fdold);
 	shp->fdstatus[fdold] = IOCLOSE;
@@ -936,6 +944,9 @@ int	sh_pipe(register int pv[])
 		sh_close(fd);
 	else
 		pv[out] = sh_iomovefd(fd);
+
+	VALIDATE_FD(shp, pv[out]);
+
 	if(fcntl(pv[out],F_SETFD,FD_CLOEXEC) >=0)
 		shp->fdstatus[pv[out]] |= IOCLEX;
 	shp->fdstatus[pv[out]] = (out?IOWRITE:IOREAD);
@@ -968,6 +979,9 @@ int	sh_pipe(register int pv[])
 		errormsg(SH_DICT,ERROR_system(1),e_pipe);
 	}
 	fcntl(pv[out],F_SETFD,FD_CLOEXEC);
+
+	VALIDATE_FD(shp, pv[out]);
+
 	shp->fdstatus[pv[out]] |= IOCLEX;
 	pv[1-out] = -1;
 	pv[2] = port;
@@ -997,9 +1011,13 @@ static int pat_line(const regex_t* rp, c
 static int io_patseek(Shell_t *shp, regex_t *rp, Sfio_t* sp, int flags)
 {
 	char	*cp, *match;
-	int	r, fd=sffileno(sp), close_exec = shp->fdstatus[fd]&IOCLEX;
+	int	r, fd, close_exec;
 	int	was_share,s=(PIPE_BUF>SF_BUFSIZE?SF_BUFSIZE:PIPE_BUF);
 	size_t	n,m;
+
+	fd = sffileno(sp);
+	VALIDATE_FD(shp, fd);
+	close_exec = shp->fdstatus[fd]&IOCLEX;
 	shp->fdstatus[sffileno(sp)] |= IOCLEX;
 	if(fd==0)
 		was_share = sfset(sp,SF_SHARE,1);
@@ -1033,12 +1051,17 @@ static int io_patseek(Shell_t *shp, rege
 
 static Sfoff_t	file_offset(Shell_t *shp, int fn, char *fname)
 {
-	Sfio_t		*sp = shp->sftable[fn];
+	Sfio_t		*sp;
 	char		*cp;
 	Sfoff_t		off;
 	struct Eof	endf;
 	Namval_t	*mp = nv_open("EOF",shp->var_tree,0);
 	Namval_t	*pp = nv_open("CUR",shp->var_tree,0);
+
+	VALIDATE_FD(shp, fn);
+
+	sp = shp->sftable[fn];
+
 	memset(&endf,0,sizeof(struct Eof));
 	endf.fd = fn;
 	endf.hdr.disc = &EOF_disc;
@@ -1216,7 +1239,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 			if((iof&IOLSEEK) || ((iof&IOMOV) && *fname=='-'))
 				fn = nv_getnum(np);
 		}
-		if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
+		if (!VALIDATE_FD(shp, fn))
 			errormsg(SH_DICT,ERROR_system(1),e_file+4);
 		if(iof&IOLSEEK)
 		{
@@ -1259,6 +1282,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 						message = e_file;
 						goto fail;
 					}
+					VALIDATE_FD(shp, dupfd);
 					if(shp->subshell && dupfd==1)
 					{
 						if(sfset(sfstdout,0,0)&SF_STRING)
@@ -1295,8 +1319,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 					goto traceit;
 				if((fd=sh_fcntl(dupfd,F_DUPFD,3))<0)
 					goto fail;
-				if(fd>= shp->gd->lim.open_max)
-					sh_iovalidfd(shp,fd);
+				VALIDATE_FD(shp, fd);
 				sh_iocheckfd(shp,dupfd);
 				shp->fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX);
 				if(toclose<0 && shp->fdstatus[fd]&IOREAD)
@@ -1410,7 +1433,11 @@ int	sh_redirect(Shell_t *shp,struct iono
 			}
 			if(iof&IOLSEEK)
 			{
-				Sfio_t *sp = shp->sftable[fn];
+				Sfio_t *sp;
+
+				VALIDATE_FD(shp, fn);
+
+				sp = shp->sftable[fn];
 				r = shp->fdstatus[fn];
 				if(!(r&(IOSEEK|IONOSEEK)))
 					r = sh_iocheckfd(shp,fn);
@@ -1491,6 +1518,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 			}
 			if(fd<0)
 			{
+				VALIDATE_FD(shp, fn);
 				if(sh_inuse(shp,fn) || (fn && fn==shp->infd))
 				{
 					if(fn>9 || !(shp->inuse_bits&(1<<fn)))
@@ -1510,7 +1538,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 					{
 						if((fn=fcntl(fd,F_DUPFD,10)) < 0)
 							goto fail;
-						if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
+						if (!VALIDATE_FD(shp, fn))
 							goto fail;
 						if(flag!=2 || shp->subshell)
 							sh_iosave(shp,fn,indx|0x10000,tname?fname:(trunc?Empty:0));
@@ -1701,7 +1729,12 @@ void sh_iosave(Shell_t *shp, register in
 	filemap[shp->topfd++].save_fd = savefd;
 	if(savefd >=0)
 	{
-		register Sfio_t* sp = shp->sftable[origfd];
+		register Sfio_t* sp;
+
+		VALIDATE_FD(shp, origfd);
+		VALIDATE_FD(shp, savefd);
+
+		sp = shp->sftable[origfd];
 		/* make saved file close-on-exec */
 		sh_fcntl(savefd,F_SETFD,FD_CLOEXEC);
 		if(origfd==job.fd)
@@ -1734,6 +1767,7 @@ void	sh_iounsave(Shell_t* shp)
 			filemap[newfd++] = filemap[fd];
 		else
 		{
+			VALIDATE_FD(shp, savefd);
 			shp->sftable[savefd] = 0;
 			sh_close(savefd);
 		}
@@ -1757,16 +1791,19 @@ void	sh_iorestore(Shell_t *shp, int last
 		{
 			if ((savefd = filemap[fd].save_fd) >= 0)
 			{
+				VALIDATE_FD(shp, savefd);
 				shp->sftable[savefd] = 0;
 				sh_close(savefd);
 			}
 			continue;
 		}
 		origfd = filemap[fd].orig_fd;
+		VALIDATE_FD(shp, origfd);
 		if(origfd<0)
 		{
 			/* this should never happen */
 			savefd = filemap[fd].save_fd;
+			VALIDATE_FD(shp, savefd);
 			shp->sftable[savefd] = 0;
 			sh_close(savefd);
 			return;
@@ -1778,6 +1815,7 @@ void	sh_iorestore(Shell_t *shp, int last
 		sh_close(origfd);
 		if ((savefd = filemap[fd].save_fd) >= 0)
 		{
+			VALIDATE_FD(shp, savefd);
 			sh_fcntl(savefd, F_DUPFD, origfd);
 			if(savefd==job.fd)
 				job.fd=origfd;
@@ -2035,6 +2073,9 @@ static ssize_t slowread(Sfio_t *iop,void
 int sh_iocheckfd(Shell_t *shp, register int fd)
 {
 	register int flags, n;
+
+	VALIDATE_FD(shp, fd);
+
 	if((n=shp->fdstatus[fd])&IOCLOSE)
 		return(n);
 	if(!(n&(IOREAD|IOWRITE)))
@@ -2226,7 +2267,7 @@ static void	sftrack(Sfio_t* sp, int flag
 		return;
 	}
 #endif
-	if(fd<0 || fd==PSEUDOFD || (fd>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fd)))
+	if(fd<0 || fd==PSEUDOFD || !VALIDATE_FD(shp, fd))
 		return;
 	if(sh_isstate(SH_NOTRACK))
 		return;
@@ -2495,6 +2536,8 @@ ssize_t sh_read(register int fd, void* b
 {
 	Shell_t *shp = sh_getinterp();
 	register Sfio_t *sp;
+
+	VALIDATE_FD(shp, fd);
 	if(sp=shp->sftable[fd])
 		return(sfread(sp,buff,n));
 	else
@@ -2509,6 +2552,8 @@ ssize_t sh_write(register int fd, const
 {
 	Shell_t *shp = sh_getinterp();
 	register Sfio_t *sp;
+
+	VALIDATE_FD(shp, fd);
 	if(sp=shp->sftable[fd])
 		return(sfwrite(sp,buff,n));
 	else
@@ -2523,6 +2568,8 @@ off_t sh_seek(register int fd, off_t off
 {
 	Shell_t *shp = sh_getinterp();
 	register Sfio_t *sp;
+
+	VALIDATE_FD(shp, fd);
 	if((sp=shp->sftable[fd]) && (sfset(sp,0,0)&(SF_READ|SF_WRITE)))
 		return(sfseek(sp,offset,whence));
 	else
@@ -2534,6 +2581,9 @@ int sh_dup(register int old)
 {
 	Shell_t *shp = sh_getinterp();
 	register int fd = dup(old);
+
+	VALIDATE_FD(shp, old);
+	VALIDATE_FD(shp, fd);
 	if(fd>=0)
 	{
 		if(shp->fdstatus[old] == IOCLOSE)
@@ -2555,13 +2605,15 @@ int sh_fcntl(register int fd, int op, ..
 	arg =  va_arg(ap, int) ;
 	va_end(ap);
 	newfd = fcntl(fd,op,arg);
+
+	VALIDATE_FD(shp, fd);
+	VALIDATE_FD(shp, newfd);
+
 	if(newfd>=0) switch(op)
 	{
 	    case F_DUPFD:
 		if(shp->fdstatus[fd] == IOCLOSE)
 			shp->fdstatus[fd] = 0;
-		if(newfd>=shp->gd->lim.open_max)
-			sh_iovalidfd(shp,newfd);
 		shp->fdstatus[newfd] = (shp->fdstatus[fd]&~IOCLEX);
 		if(fdnotify)
 			(*fdnotify)(fd,newfd);
@@ -2630,6 +2682,7 @@ Sfio_t *sh_iogetiop(int fd, int mode)
 		return(iop);
 	if(mode==SF_READ && !(n&IOREAD))
 		return(iop);
+	VALIDATE_FD(shp, fd);
 	if(!(iop = shp->sftable[fd]))
 		iop=sh_iostream(shp,fd);
 	return(iop);
@@ -2649,7 +2702,10 @@ Sfio_t	*sh_fd2sfio(int fd)
 {
 	Shell_t	*shp = sh_getinterp();
 	register int status;
-	Sfio_t *sp = shp->sftable[fd];
+	Sfio_t *sp;
+
+	VALIDATE_FD(shp, fd);
+	sp = shp->sftable[fd];
 	if(!sp  && (status = sh_iocheckfd(shp,fd))!=IOCLOSE)
 	{
 		register int flags=0;
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/lex.c	2015-02-24 13:25:19.370183959 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/lex.c	2015-03-04 13:27:49.211457345 -0800
@@ -25,6 +25,9 @@
  * AT&T Labs
  *
  */
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
 
 #include	<ast.h>
 #include	<stak.h>
@@ -2122,6 +2125,7 @@ void	sh_syntax(Lex_t *lp)
 	else
 		lp->lastline = shp->inlineno;
 	tokstr = fmttoken(lp,tok,tokbuf);
+	VALIDATE_FD(shp, shp->infd);
 	if((sp=fcfile()) || (shp->infd>=0 && (sp=shp->sftable[shp->infd])))
 	{
 		/* clear out any pending input */
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/macro.c	2015-02-24 13:25:19.363200741 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/macro.c	2015-03-04 13:27:49.212566247 -0800
@@ -2121,6 +2121,7 @@ static void comsubst(Mac_t *mp,register
 			sh_popcontext(mp->shp,&buff);
 			if(r==0 && ip && (ip->iofile&IOLSEEK))
 			{
+				VALIDATE_FD(mp->shp, fd);
 				if(sp=mp->shp->sftable[fd])
 					num = sftell(sp);
 				else
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/main.c	2015-02-24 13:25:19.364162232 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/main.c	2015-03-04 13:27:49.213386462 -0800
@@ -26,6 +26,9 @@
  * AT&T Labs
  *
  */
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
 
 #include	<ast.h>
 #include	<sfio.h>
@@ -376,8 +379,10 @@ static void	exfile(register Shell_t *shp
 		if(fno > 0)
 		{
 			int r;
+			VALIDATE_FD(shp, fno);
 			if(fno < 10 && ((r=sh_fcntl(fno,F_DUPFD,10))>=10))
 			{
+				VALIDATE_FD(shp, r);
 				shp->fdstatus[r] = shp->fdstatus[fno];
 				sh_close(fno);
 				fno = r;
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/path.c	2015-02-24 13:25:19.360898415 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/path.c	2015-03-04 13:27:49.214381188 -0800
@@ -23,6 +23,9 @@
  * AT&T Labs
  *
  */
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
 
 #include	"defs.h"
 #include	<fcin.h>
@@ -1272,6 +1275,7 @@ static void exscript(Shell_t *shp,regist
 	if(sp=fcfile())
 		while(sfstack(sp,SF_POPSTACK));
 	job_clear();
+	VALIDATE_FD(shp, shp->infd);
 	if(shp->infd>0 && (shp->fdstatus[shp->infd]&IOCLEX))
 		sh_close(shp->infd);
 	sh_setstate(sh_state(SH_FORKED));
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/subshell.c	2015-02-24 13:25:19.363479570 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/subshell.c	2015-03-04 14:05:03.665801329 -0800
@@ -125,6 +125,7 @@ void	sh_subtmpfile(Shell_t *shp)
 		if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
 		{
 			fcntl(fd,F_SETFD,FD_CLOEXEC);
+			VALIDATE_FD(shp, fd);
 			shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
 			close(1);
 		}
@@ -151,6 +152,7 @@ void	sh_subtmpfile(Shell_t *shp)
 		}
 		else
 		{
+			VALIDATE_FD(shp, fd);
 			shp->fdstatus[fd] = IOREAD|IOWRITE;
 			sfsync(sfstdout);
 			if(fd==1)
@@ -679,8 +681,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
 					((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
 					errormsg(SH_DICT,ERROR_system(1),e_toomany);
 				}
-				if(fd >= shp->gd->lim.open_max)
-					sh_iovalidfd(shp,fd);
+				VALIDATE_FD(shp, fd);
 				shp->sftable[fd] = iop;
 				fcntl(fd,F_SETFD,FD_CLOEXEC);
 				shp->fdstatus[fd] = (shp->fdstatus[1]|IOCLEX);
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/xec.c	2015-02-24 13:25:19.365424099 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/xec.c	2015-03-04 14:05:12.823587666 -0800
@@ -117,6 +117,8 @@ static int iousepipe(Shell_t *shp)
 	usepipe++;
 	fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
 	subpipe[2] = fcntl(1,F_DUPFD,10);
+	VALIDATE_FD(shp, subpipe[1]);
+	VALIDATE_FD(shp, subpipe[2]);	
 	fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
 	shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
 	close(1);
@@ -141,6 +143,7 @@ static void iounpipe(Shell_t *shp)
 	char buff[SF_BUFSIZE];
 	close(1);
 	fcntl(subpipe[2], F_DUPFD, 1);
+	VALIDATE_FD(shp, subpipe[2]);
 	shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
 	--usepipe;
 	if(subdup) for(n=0; n < 10; n++)
@@ -886,6 +889,7 @@ static int sh_coexec(Shell_t *shp,const
 			if(filt > 2)
 			{
 				shp->coutpipe = shp->inpipe[1];
+				VALIDATE_FD(shp, shp->coutpipe);
 				shp->fdptrs[shp->coutpipe] = &shp->coutpipe;
 			}
 		}
@@ -1646,6 +1650,7 @@ int sh_exec(register const Shnode_t *t,
 						if(shp->cpipe[0]<0 || shp->cpipe[1] < 0)
 						{
 							sh_copipe(shp,shp->outpipe=shp->cpipe,0);
+							VALIDATE_FD(shp, shp->cpipe[0]);
 							shp->fdptrs[shp->cpipe[0]] = shp->cpipe;
 						}
 						sh_copipe(shp,shp->inpipe=pipes,0);
@@ -3623,6 +3628,8 @@ static void coproc_init(Shell_t *shp, in
 		if((outfd=shp->cpipe[1]) < 10) 
 		{
 		        int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
+			VALIDATE_FD(shp, outfd);
+			VALIDATE_FD(shp, fd);
 			if(fd>=10)
 			{
 			        shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);
@@ -3631,6 +3638,9 @@ static void coproc_init(Shell_t *shp, in
 				shp->cpipe[1] = fd;
 			}
 		}
+		VALIDATE_FD(shp, shp->cpipe[0]);
+		VALIDATE_FD(shp, shp->cpipe[1]);
+
 		if(fcntl(*shp->cpipe,F_SETFD,FD_CLOEXEC)>=0)
 			shp->fdstatus[shp->cpipe[0]] |= IOCLEX;
 		shp->fdptrs[shp->cpipe[0]] = shp->cpipe;
@@ -3641,7 +3651,9 @@ static void coproc_init(Shell_t *shp, in
 	shp->outpipe = shp->cpipe;
 	sh_pipe(shp->inpipe=pipes);
 	shp->coutpipe = shp->inpipe[1];
+	VALIDATE_FD(shp, shp->coutpipe);
 	shp->fdptrs[shp->coutpipe] = &shp->coutpipe;
+	VALIDATE_FD(shp, shp->outpipe[0]);
 	if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
 		shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
 }
@@ -3812,6 +3824,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
 				int fd = shp->inpipe[1];
 				sh_iosave(shp,0,buffp->topfd,(char*)0);
 				sh_iorenumber(shp,shp->inpipe[0],0);
+				VALIDATE_FD(shp, fd);
 				if(fd>=0 && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(fd,F_SETFD,FD_CLOEXEC)>=0)
 					shp->fdstatus[fd] |= IOCLEX;
 			}
@@ -3823,6 +3836,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
 #endif /* SHOPT_COSHELL */
 				sh_iosave(shp,1,buffp->topfd,(char*)0);
 				sh_iorenumber(shp,sh_dup(shp->outpipe[1]),1);
+				VALIDATE_FD(shp, shp->outpipe[0]);
 				if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
 					shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
 			}
@@ -3862,6 +3876,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
 			signal(SIGQUIT,sh_fault);
 			signal(SIGINT,sh_fault);
 		}
+		VALIDATE_FD(shp, shp->inpipe[1]);
 		if((otype&FPIN) && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(shp->inpipe[1],F_SETFD,FD_CLOEXEC)>=0)
 			shp->fdstatus[shp->inpipe[1]] &= ~IOCLEX;
 		if(t->fork.forkio || otype)