From d2b0f822d8799a4e35f38ae80b3ee00622de04a7 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Tue, 31 Dec 2024 02:34:39 +0100 Subject: [PATCH] io_prompt(): fix use-after-free in PS2 handling (re: 2322f939) If a PS2.get discipline function is set (like in our shipped 'bin/package use' environment), then the value of PS2 is pushed on the stack (see nvdisc.c:429). So, restoring the stack state after getting the PS2 value may free the space that contains the value and a use-after-free may occur when calling sfputr to output it. src/cmd/ksh93/sh/io.c: io_prompt(): - Output the obtained value of PS2 before restoring the stack. - Get rid of the ugly gotos. --- src/cmd/ksh93/sh/io.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index b29892a3e357..991b943e095d 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -2167,15 +2167,13 @@ static int io_prompt(Sfio_t *iop,int flag) c = *++cp; /* print out line number if not !! */ if(c!= HIST_CHAR) - { sfprintf(sfstderr,"%d", sh.hist_ptr?(int)sh.hist_ptr->histind:++cmdno); - } if(c==0) - goto done; + break; } sfputc(sfstderr,c); } - goto done; + break; } case 2: { @@ -2183,19 +2181,17 @@ static int io_prompt(Sfio_t *iop,int flag) * in case we're executing a PS2.get discipline function at parse time. */ int savestacktop = stktell(sh.stk); void *savestackptr = stkfreeze(sh.stk,0); - cp = nv_getval(sh_scoped(PS2NOD)); + if (cp = nv_getval(sh_scoped(PS2NOD))) + sfputr(sfstderr,cp,-1); + /* Restore the stack. (If nv_getval ran a PS2.get discipline, this may free the space cp points to.) */ stkset(sh.stk, savestackptr, savestacktop); break; } case 3: - cp = nv_getval(sh_scoped(PS3NOD)); + if (cp = nv_getval(sh_scoped(PS3NOD))) + sfputr(sfstderr,cp,-1); break; - default: - goto done; } - if(cp) - sfputr(sfstderr,cp,-1); -done: if(*sh.prompt && (endprompt=(char*)sfreserve(sfstderr,0,0))) *endprompt = 0; sfset(sfstderr,sfflags&SFIO_READ|SFIO_SHARE|SFIO_PUBLIC,1);