Skip to content

Commit 4604df9

Browse files
committed
Stack robustness fixes from OpenSUSE
Three OpenSUSE patches from: https://build.opensuse.org/package/show/shells/ksh As usual, the relevant bug is not currently public: https://bugzilla.opensuse.org/show_bug.cgi?id=844071 src/cmd/ksh93/sh/xec.c: sh_debug()/sh_exec(): - Fix stk restoration. [bnc#844071] src/lib/libast/misc/stk.c: - Fix stk aliasing code. [bnc#844071] (ksh93-stkalias.dif) - Make a unknown location fatal in stkset() so that we get a core dump right away instead of later in an unrelated part of code. (ksh93-stkset-abort.dif) src/lib/libast/man/stk.3, src/lib/libast/man/stak.3: - Update manual with new stkset() behaviour. (93u+m addition) (Note that stak is implemented as macros that translate to stk)
1 parent c5bd687 commit 4604df9

4 files changed

Lines changed: 19 additions & 13 deletions

File tree

‎src/cmd/ksh93/sh/xec.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc
646646
Stk_t *stkp=shp->stk;
647647
struct sh_scoped savst;
648648
Namval_t *np = SH_COMMANDNOD;
649-
char *sav = stkptr(stkp,0);
650649
int n=4, offset=stktell(stkp);
650+
char *sav = stkfreeze(stkp,0);
651651
const char *cp = "+=( ";
652652
Sfio_t *iop = stkstd;
653653
short level;
@@ -702,7 +702,7 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc
702702
nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
703703
shp->st = savst;
704704
if(sav != stkptr(stkp,0))
705-
stkset(stkp,sav,0);
705+
stkset(stkp,sav,offset);
706706
else
707707
stkseek(stkp,offset);
708708
return(n);
@@ -962,7 +962,7 @@ int sh_exec(register const Shnode_t *t, int flags)
962962
int ntflag = 0;
963963
#endif
964964
int topfd = shp->topfd;
965-
char *sav=stkptr(stkp,0);
965+
char *sav=stkfreeze(stkp,0);
966966
char *cp=0, **com=0, *comn;
967967
int argn;
968968
int skipexitset = 0;

‎src/lib/libast/man/stak.3‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ the given \fIaddress\fP, and sets the current object to the given
109109
\fIaddress\fP.
110110
The top of the current object is set to \fIoffset\fP bytes from
111111
current object.
112-
If \fIaddress\fP is not the address of an object on the
113-
stack the result is undefined.
112+
If \fIaddress\fP is null, the stack is reset to the beginning.
113+
If it is non-null, but is not the address of an object on the
114+
stack, the program aborts and dumps core.
114115
.PP
115116
The remaining functions are used to build the current object incrementally.
116117
An object that is built incrementally on the stack will

‎src/lib/libast/man/stk.3‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ the given \fIaddress\fP, and sets the current object to the given
110110
\fIaddress\fP.
111111
The top of the current object is set to \fIoffset\fP bytes from
112112
current object.
113-
If \fIaddress\fP is not the address of an object on the
114-
stack the result is undefined.
113+
If \fIaddress\fP is null, the stack is reset to the beginning.
114+
If it is non-null, but is not the address of an object on the
115+
stack, the program aborts and dumps core.
115116
.PP
116117
The \f5sfio\fP(3) output functions can be used to build
117118
current object incrementally.

‎src/lib/libast/misc/stk.c‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ int stkon(register Sfio_t * stream, register char* loc)
331331
}
332332
/*
333333
* reset the bottom of the current stack back to
334-
* if is not in this stack, then the stack is reset to the beginning
334+
* if is null, then the stack is reset to the beginning
335+
* if is not in this stack, the program dumps core
335336
* otherwise, the top of the stack is set to stkbot+
336-
*
337337
*/
338338
char *stkset(register Sfio_t * stream, register char* loc, size_t offset)
339339
{
@@ -377,6 +377,9 @@ char *stkset(register Sfio_t * stream, register char* loc, size_t offset)
377377
break;
378378
frames++;
379379
}
380+
/* not found: produce a useful stack trace now instead of a useless one later */
381+
if(loc)
382+
abort();
380383
/* set stack back to the beginning */
381384
cp = (char*)(fp+1);
382385
if(frames)
@@ -503,7 +506,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
503506
register char *cp, *dp=0;
504507
register size_t m = stktell(stream);
505508
size_t endoff;
506-
char *end=0;
509+
char *end=0, *oldbase=0;
507510
int nn=0,add=1;
508511
n += (m + sizeof(struct frame)+1);
509512
if(sp->stkflags&STK_SMALL)
@@ -519,6 +522,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
519522
dp=sp->stkbase;
520523
sp->stkbase = ((struct frame*)dp)->prev;
521524
end = fp->end;
525+
oldbase = dp;
522526
}
523527
endoff = end - dp;
524528
cp = newof(dp, char, n, nn*sizeof(char*));
@@ -545,10 +549,10 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
545549
if(fp->nalias=nn)
546550
{
547551
fp->aliases = (char**)fp->end;
548-
if(end && nn>1)
549-
memmove(fp->aliases,end,(nn-1)*sizeof(char*));
552+
if(end && nn>add)
553+
memmove(fp->aliases,end,(nn-add)*sizeof(char*));
550554
if(add)
551-
fp->aliases[nn-1] = dp + roundof(sizeof(struct frame),STK_ALIGN);
555+
fp->aliases[nn-1] = oldbase + roundof(sizeof(struct frame),STK_ALIGN);
552556
}
553557
if(m && !dp)
554558
{

0 commit comments

Comments
 (0)