ksh: Path-bound builtins cannot be executed by direct path

There are at least two bugs with the /opt/ast/bin virtual directory path search and access mechanism for path-bound builtins.

One is that preceding command-local PATH assignments don’t work as specified:

$ builtin -d cat  # make sure it's path-bound
$ (PATH=/opt/ast/bin:$PATH; cat --version)
  version         cat (AT&T Research) 2012-05-31
$ PATH=/opt/ast/bin:$PATH cat --version
cat: illegal option -- -
usage: cat [-benstuv] [file ...]

The second output is my external cat, which is a bug. Both should show the AT&T version message.

The second bug is simpler:

$ /opt/ast/bin/cat
-ksh: /opt/ast/bin/cat: not found

This is ridiculous and probably violates POSIX. If a path can be found in $PATH it should actually be invokable as that path. This also means you cannot trust the output of whence -p and command -v when /opt/ast/bin is in the $PATH. For example, this common idiom breaks:

$ (PATH=/opt/ast/bin:$PATH; u=$(whence -p cat) && "$u" --version)                  
-ksh: /opt/ast/bin/cat: not found [No such file or directory]

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 28

Commits related to this issue

Most upvoted comments

I have a hard time caring about any of these. I’ve never seen any evidence that the restricted mode is actually used by anyone. Even if it is used, it is meant for administrators to allow users to run a limited number of basic commands to do simple things. None of the 3 things above are likely to be in the set of requirements for that purpose. So I think we should just leave well enough alone here.

Sure. This behavior should at least be documented though:

--- a/src/lib/libcmd/date.c
+++ b/src/lib/libcmd/date.c
@@ -31,8 +31,8 @@ static const char usage[] =
 "[--catalog?" ERROR_CATALOG "]"
 "[+NAME?date - set/list/convert dates]"
 "[+DESCRIPTION?\bdate\b sets the current date and time (with appropriate"
-"	privilege), lists the current date or file dates, or converts"
-"	dates.]"
+"	privileges, provided the shell isn't in restricted mode), lists"
+"	the current date or file dates, or converts dates.]"
 "[+?Most common \adate\a forms are recognized, including those for"
 "	\bcrontab\b(1), \bls\b(1), \btouch\b(1), and the default"
 "	output from \bdate\b itself.]"
--- a/src/lib/libcmd/getconf.c
+++ b/src/lib/libcmd/getconf.c
@@ -56,7 +56,8 @@ static const char usage[] =
 "	system calls."
 "	Invalid options and/or names not supported by \bastgetconf\b(3) cause"
 "	the default native \bgetconf\b, named by \b$(getconf GETCONF)\b, to"
-"	be executed.]"
+"	be executed (unless the shell is in restricted mode, in which case"
+"	an error will occur).]"
 
 "[a:all?Call the native \bgetconf\b(1) with option \b-a\b.]"
 "[b:base?List base variable name sans call and standard prefixes.]"
--- a/src/lib/libcmd/uname.c
+++ b/src/lib/libcmd/uname.c
@@ -37,7 +37,8 @@ static const char usage[] =
 "	separated, on a single line. When more than one option is specified"
 "	the output is in the order specified by the \b-A\b option below."
 "	Unsupported option values are listed as \a[option]]\a. If any unknown"
-"	options are specified, the OS default \buname\b(1) is called.]"
+"	options are specified, the OS default \buname\b(1) is called (unless"
+"	the shell is in restricted mode, in which case an error will occur).]"
 "[+?If any \aname\a operands are specified then the \bsysinfo\b(2) values"
 "	for each \aname\a are listed, separated by space, on one line."
 "	\bgetconf\b(1), a pre-existing \astandard\a interface, provides"

I’ve encountered two bugs in the pathbound-builtins branch. The first bug is that running a builtin using /opt/ast/bin works in restricted shells, even though it shouldn’t:

$ PATH=/opt/ast/bin:$PATH arch/linux.i386-64/bin/ksh -o restricted

# The first two commands function correctly
$ cat --version
  version         cat (AT&T Research) 2012-05-31
$ /bin/cat --version
arch/linux.i386-64/bin/ksh: /bin/cat: restricted

# This one, however, should throw an error
$ /opt/ast/bin/cat --version
  version         cat (AT&T Research) 2012-05-31

I’d say this behavior is a bug because it’s not behaving as documented in the man page, which states rksh forbids this practice:

specifying path or command names containing /,

This patch should fix this issue:

--- a/src/cmd/ksh93/sh/parse.c
+++ b/src/cmd/ksh93/sh/parse.c
@@ -1439,7 +1439,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
 		{
 			if(!(argp->argflag&ARG_RAW))
 				argno = -1;
-			if(argno>=0 && argno++==cmdarg && !(flag&SH_ARRAY))
+			if(argno>=0 && argno++==cmdarg && !(flag&SH_ARRAY) && !(*argp->argval=='/' && sh_isoption(SH_RESTRICTED)))
 			{
 				/* check for builtin command (including path-bound builtins executed by full pathname) */
 				Namval_t *np=nv_bfsearch(argp->argval,lexp->sh->fun_tree, (Namval_t**)&t->comnamq,(char**)0);
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -1222,7 +1222,7 @@ int sh_exec(register const Shnode_t *t, int flags)
 				shp->lastpath = 0;
 				if(!np)
 				{
-					if(*com0 == '/')
+					if(*com0 == '/' && !sh_isoption(SH_RESTRICTED))
 					{
 						/* Check for path-bound builtin referenced by absolute canonical path, in
 						   case the parser didn't provide a pointer (e.g. '$(whence -p cat) foo') */

For the second bug, the getconf, uname and (possibly) date libcmd builtins throw restricted errors when given an unrecognized option, rather than execute the equivalent external command:

$ PATH=/opt/ast/bin:$PATH arch/*/bin/ksh -o restricted
$ getconf -z
getconf: -p: restricted
$ uname -z
uname: -p: restricted

This is presumably occurs because uname and date run their external versions with command -px (while the new patch for getconf also uses this method). I tried using a diff that just uses command -x, but that doesn’t work.

When I comment out nv_search, the crash stops occurring:

--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -1226,7 +1226,7 @@ int sh_exec(register const Shnode_t *t, int flags)
 					{
 						/* Check for path-bound builtin referenced by absolute canonical path, in
 						   case the parser didn't provide a pointer (e.g. '$(whence -p cat) foo') */
-						np = nv_search(com0, shp->bltin_tree, 0);
+						/*np = nv_search(com0, shp->bltin_tree, 0);*/
 					}
 					else if(strchr(com0,'/'))
 					{

I’ve managed to reproduce the crash on Artix Linux using CCFLAGS='-O0 -g -D_std_malloc'. Backtrace from gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000559de99e3c1f in print (sp=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbd8>, look=0x0, name=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbd0>, 
    path=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbc8>, listflags=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbc4>, conferror=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbb8>)
    at /home/johno/Downloads/ksh/src/lib/libast/port/astconf.c:984
984	{
(gdb) bt
#0  0x0000559de99e3c1f in print (sp=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbd8>, look=0x0, name=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbd0>, 
    path=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbc8>, listflags=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbc4>, conferror=<error reading variable: Cannot access memory at address 0x7ffc3dfbfbb8>)
    at /home/johno/Downloads/ksh/src/lib/libast/port/astconf.c:984
#1  0x0000559de99e534f in astgetconf (name=0x559deac73211 "ARG_MAX", path=0x559de9a75308 <root> "/", value=0x0, flags=6144, conferror=0x559de99901b8 <errorf>) at /home/johno/Downloads/ksh/src/lib/libast/port/astconf.c:1458
#2  0x0000559de9a03580 in b_getconf (argc=2, argv=0x559dead8d7b0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:267
#3  0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#4  0x0000559de995087b in sh_run (argn=2, argv=0x559dead8d610) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#5  0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8d620, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#6  0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#7  0x0000559de995087b in sh_run (argn=2, argv=0x559dead8d480) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#8  0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8d490, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#9  0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#10 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8d2f0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#11 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8d300, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#12 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#13 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8d160) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#14 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8d170, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#15 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#16 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8cfd0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#17 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8cfe0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#18 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#19 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8ce40) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#20 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8ce50, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#21 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#22 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8ccb0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#23 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8ccc0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#24 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#25 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8cb20) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#26 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8cb30, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#27 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#28 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b9c0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#29 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b9d0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#30 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#31 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b830) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#32 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b840, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#33 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#34 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b6a0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#35 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b6b0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#36 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#37 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b510) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#38 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b520, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#39 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#40 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b380) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#41 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b390, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#42 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#43 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b1f0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#44 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b200, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#45 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#46 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8b060) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#47 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8b070, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#48 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#49 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8aed0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#50 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8aee0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#51 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#52 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8ad40) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#53 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8ad50, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#54 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#55 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8abb0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#56 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8abc0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#57 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#58 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8aa20) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#59 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8aa30, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#60 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#61 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8a890) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#62 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8a8a0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#63 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#64 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8a700) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#65 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8a710, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#66 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#67 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8a570) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#68 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8a580, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#69 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#70 0x0000559de995087b in sh_run (argn=2, argv=0x559dead8a3e0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#71 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559dead8a3f0, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405

... repeats until frame 3348

#3345 0x0000559de994bd16 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#3346 0x0000559de995087b in sh_run (argn=2, argv=0x559deac73240) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2807
#3347 0x0000559de9a03c8b in b_getconf (argc=2, argv=0x559deac73250, context=0x559de9a76aa0 <sh+1312>) at /home/johno/Downloads/ksh/src/lib/libcmd/getconf.c:405
#3348 0x0000559de994bd16 in sh_exec (t=0x0, flags=1) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1378
#3349 0x0000559de994515e in sh_subshell (shp=0x559de9a76580 <sh>, t=0x559deac731c0, flags=1, comsub=3) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/subshell.c:692
#3350 0x0000559de9923f03 in comsubst (mp=0x559deac61040, t=0x559deac731c0, type=3) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/macro.c:2196
#3351 0x0000559de991fc50 in varsub (mp=0x559deac61040) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/macro.c:1171
#3352 0x0000559de991e41d in copyto (mp=0x559deac61040, endch=0, newquote=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/macro.c:629
#3353 0x0000559de991c9b0 in sh_mactrim (shp=0x559de9a76580 <sh>, str=0x559deac71f81 "arg_max=$(getconf ARG_MAX)", mode=-1) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/macro.c:178
#3354 0x0000559de99264f7 in nv_setlist (arg=0x559deac71f70, flags=131584, typ=0x0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/name.c:304
#3355 0x0000559de994af49 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1163
#3356 0x0000559de994e1d6 in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2099
#3357 0x0000559de994e1ba in sh_exec (t=0x0, flags=0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2098
#3358 0x0000559de994e213 in sh_exec (t=0x0, flags=4) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2105
#3359 0x0000559de994e15e in sh_exec (t=0x0, flags=133) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:2087
#3360 0x0000559de994da76 in sh_exec (t=0x0, flags=133) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1939
#3361 0x0000559de994d6ad in sh_exec (t=0x0, flags=133) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1884
#3362 0x0000559de994d342 in sh_exec (t=0x0, flags=4) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/xec.c:1828
#3363 0x0000559de98eb58f in exfile (shp=0x0, iop=0x7ffc3dfc0cc0, fno=-356044271) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/main.c:585
#3364 0x0000559de98eaa62 in sh_main (ac=2, av=0x7ffc3e7bd448, userinit=0x0) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/main.c:357
#3365 0x0000559de98e9dfe in main (argc=2, argv=0x7ffc3e7bd448) at /home/johno/Downloads/ksh/src/cmd/ksh93/sh/pmain.c:45