From 7eeafe16ba9c7ec5e990a00a36e59d33a6f8d26b Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Tue, 23 Jan 2024 13:05:13 -0800 Subject: [PATCH] Fix undefined behavior in pty and .sh.match This pull request fixes a few errors that occur when ksh is built with -fsanitize=address,undefined. src/cmd/builtin/pty.c: - Use long typecasts with PROC_op1, which fixes this error under ASan: src/cmd/builtin/pty.c:356:18: runtime error: left shift of 12 by 28 places cannot be represented in type 'int' src/cmd/ksh93/sh/init.c: - Ensure mp->nodes is not NULL before making use of it. This change fixes two errors under ASan that occur during the exit and glob regression tests: src/cmd/ksh93/sh/init.c:868:6: runtime error: applying non-zero offset 18446744073709551600 to null pointer src/cmd/ksh93/sh/init.c:831:5: runtime error: applying non-zero offset 18446744073709551600 to null pointer src/lib/libast/include/proc.h: - Remove the now unused PROC_FD_CTTY macro. --- src/cmd/builtin/pty.c | 2 +- src/cmd/ksh93/sh/init.c | 64 +++++++++++++++++++---------------- src/lib/libast/include/proc.h | 1 - 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/cmd/builtin/pty.c b/src/cmd/builtin/pty.c index 86ea8f75bff5..508f375fd0f8 100644 --- a/src/cmd/builtin/pty.c +++ b/src/cmd/builtin/pty.c @@ -353,7 +353,7 @@ runcmd(char** argv, int minion, int session) if (session) { - ops[0] = PROC_FD_CTTY(minion); + ops[0] = (long)PROC_op1((long)PROC_fd_ctty,(long)minion); ops[1] = 0; } else diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 05aaa0dfd9fa..8757029c6cc8 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -828,22 +828,25 @@ static void match2d(struct match *mp) int i; Namarr_t *ap; nv_disc(SH_MATCHNOD, &mp->hdr, NV_POP); - np = nv_namptr(mp->nodes, 0); - for(i=0; i < mp->nmatch; i++) + if(mp->nodes) { - np->nvname = mp->names + 3 * i; - if(i > 9) + np = nv_namptr(mp->nodes, 0); + for(i=0; i < mp->nmatch; i++) { - *np->nvname = '0' + i / 10; - np->nvname[1] = '0' + (i % 10); + np->nvname = mp->names + 3 * i; + if(i > 9) + { + *np->nvname = '0' + i / 10; + np->nvname[1] = '0' + (i % 10); + } + else + *np->nvname = '0' + i; + nv_putsub(np, NULL, 1); + nv_putsub(np, NULL, 0); + nv_putsub(SH_MATCHNOD, NULL, i); + nv_arraychild(SH_MATCHNOD, np, 0); + np = nv_namptr(np + 1, 0); } - else - *np->nvname = '0' + i; - nv_putsub(np, NULL, 1); - nv_putsub(np, NULL, 0); - nv_putsub(SH_MATCHNOD, NULL, i); - nv_arraychild(SH_MATCHNOD, np, 0); - np = nv_namptr(np + 1, 0); } if(ap = nv_arrayptr(SH_MATCHNOD)) ap->nelem = mp->nmatch; @@ -865,25 +868,28 @@ void sh_setmatch(const char *v, int vsize, int nmatch, int match[], int index) sh.subshell = 0; if(index<0) { - np = nv_namptr(mp->nodes,0); - if(mp->index==0) - match2d(mp); - for(i=0; i < mp->nmatch; i++) + if(mp->nodes) { - nv_disc(np,&mp->hdr,NV_LAST); - nv_putsub(np,NULL,mp->index); - for(x=mp->index; x >=0; x--) - { - n = i + x*mp->nmatch; - if(mp->match[2*n+1]>mp->match[2*n]) - nv_putsub(np,Empty,ARRAY_ADD|x); - } - if((ap=nv_arrayptr(np)) && array_elem(ap)==0) + np = nv_namptr(mp->nodes,0); + if(mp->index==0) + match2d(mp); + for(i=0; i < mp->nmatch; i++) { - nv_putsub(SH_MATCHNOD,NULL,i); - _nv_unset(SH_MATCHNOD,NV_RDONLY); + nv_disc(np,&mp->hdr,NV_LAST); + nv_putsub(np,NULL,mp->index); + for(x=mp->index; x >=0; x--) + { + n = i + x*mp->nmatch; + if(mp->match[2*n+1]>mp->match[2*n]) + nv_putsub(np,Empty,ARRAY_ADD|x); + } + if((ap=nv_arrayptr(np)) && array_elem(ap)==0) + { + nv_putsub(SH_MATCHNOD,NULL,i); + _nv_unset(SH_MATCHNOD,NV_RDONLY); + } + np = nv_namptr(np+1,0); } - np = nv_namptr(np+1,0); } sh.subshell = savesub; return; diff --git a/src/lib/libast/include/proc.h b/src/lib/libast/include/proc.h index 954d6fc25c9a..53efe424f03c 100644 --- a/src/lib/libast/include/proc.h +++ b/src/lib/libast/include/proc.h @@ -68,7 +68,6 @@ #define PROC_op2(o,a,b) (((o)<<(2*PROC_ARG_BIT))|(((b)&PROC_ARG_NULL)<