From 506bd2b23aed5c363d363714ab6b1858feecba50 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 22 Aug 2020 16:03:01 +0100 Subject: [PATCH] fix SHOPT_REGRESS crash If ksh was compiled with -DSHOPT_REGRESS=1, it would immediately segfault on init. After fixing that, another segfault remained that occurred when using the --regress= command line option with an invalid option-argument. The __regress__ builtin allows tracing a few things (see '__regress__ --man' after compiling with -DSHOPT_REGRESS=1, or usage[] in src/cmd/ksh93/bltins/regress.c). It seems of limited use, but at least it can be used/tested now. src/cmd/ksh93/sh/init.c: sh_init(): - Move the call to sh_regress_init() up. The crash on init was caused by geteuid() being intercepted by regress.c before the shp->regress (== sh.regress) pointer was initialised. - The builtin can also be called using a --regress= option-argument on the ksh command line. Before calling b___regress__() to parse that, temporarily change error_info.exit so any usage error calls exit(3) instead of sh_exit(), as the latter assumes a fully defined shell state and this call is done before the shell is fully initialised. --- src/cmd/ksh93/sh/init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 014427eee..23f6d28a3 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -1220,6 +1220,9 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) { beenhere = 1; shp = &sh; +#if SHOPT_REGRESS + sh_regress_init(shp); +#endif shgd = newof(0,struct shared,1,0); shgd->current_pid = shgd->pid = getpid(); shgd->ppid = getppid(); @@ -1265,7 +1268,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) char** av = argv; char* regress[3]; - sh_regress_init(shp); regress[0] = "__regress__"; regress[2] = 0; /* NOTE: only shp is used by __regress__ at this point */ @@ -1287,7 +1289,9 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) break; nopt = optctx(0, 0); oopt = optctx(nopt, 0); + error_info.exit = exit; /* avoid crash on b___regress__ error as shell is not fully initialized */ b___regress__(2, regress, &shp->bltindata); + error_info.exit = sh_exit; optctx(oopt, nopt); } }