Skip to content

Commit

Permalink
Fix undefined behavior in 'pty' and '.sh.match' (#708)
Browse files Browse the repository at this point in the history
This commit fixes a few errors that occur when ksh is built with
-fsanitize=address,undefined.

src/lib/libast/include/proc.h:
- Use long typecasts in PROC_op* macros to make the bit shifts safe.
  This fixes a shift overflow in the expansion of PROC_FD_CTTY():
      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
  • Loading branch information
JohnoKing authored Jan 31, 2024
1 parent 9b04cc3 commit 3862782
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 32 deletions.
64 changes: 35 additions & 29 deletions src/cmd/ksh93/sh/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,22 +827,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;
Expand All @@ -864,25 +867,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;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/libast/include/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -64,8 +64,8 @@

#define PROC_fd_ctty 0xc

#define PROC_op1(o,a) (((o)<<(2*PROC_ARG_BIT))|((a)&((PROC_ARG_NULL<<PROC_ARG_BIT)|PROC_ARG_NULL)))
#define PROC_op2(o,a,b) (((o)<<(2*PROC_ARG_BIT))|(((b)&PROC_ARG_NULL)<<PROC_ARG_BIT)|((a)&PROC_ARG_NULL))
#define PROC_op1(o,a) (((long)(o)<<(2*PROC_ARG_BIT))|((long)(a)&((PROC_ARG_NULL<<PROC_ARG_BIT)|PROC_ARG_NULL)))
#define PROC_op2(o,a,b) (((long)(o)<<(2*PROC_ARG_BIT))|(((long)(b)&PROC_ARG_NULL)<<PROC_ARG_BIT)|((long)(a)&PROC_ARG_NULL))

#define PROC_FD_CLOSE(p,f) PROC_op2(PROC_fd_dup|(f),p,PROC_ARG_NULL)
#define PROC_FD_CTTY(f) PROC_op1(PROC_fd_ctty,f)
Expand Down

0 comments on commit 3862782

Please sign in to comment.