cdesktopenv/src/cmd/ksh93
Martijn Dekker b3050769ea Fix 'return' emitting signals; allow arbitrary return values
When a global EXIT trap is set, and a ksh-style function exits with
a status > 256 that could have been the result of a signal, then
the shell incorrectly issues that signal to itself. Depending on
the signal, this causes ksh to terminate itself ungracefully:

    $ cat /tmp/exit267
    trap 'echo OK' EXIT  # This trap triggers the crash
    function foo { return 267; }
    foo
    $ bash /tmp/exit267
    OK
    $ ksh-3aee10d7 /tmp/exit267
    OK
    $ ksh /tmp/exit267
    Memory fault(coredump)

On most systems, status 267 corresponds to SIGSEGV. The reported
memory fault is not real; it results from ksh incorrectly killing
itself with that signal.

The problem is caused by two factors:

1. As of 93u+ 2012-08-01, ksh explicitly allows 'return' to use an
   exit status corresponding to a signal (from 257 to end of signal
   range). The rest of the integer range is trunctated to 8 bits.
   This is contrary to both 'man ksh' and 'return --man' which both
   say it's always truncated to 8 bits. Plus, combined with point 2
   below, this new behaviour is nonsensical, as 'return' has no
   business actually generating signals. However, a couple of
   regression tests now depend on this, as may some scripts.

2. When a ksh-style function does not handle a signal, the signal
   is passed down to the parent environment and ksh does this by
   reissuing the signal to its own process after leaving the
   function scope. However, it does this by checking the exit
   status, which is very bad practice as there is no guarantee
   that an exit status corresponding to a signal was in fact
   produced by a signal, particularly after they changed the
   behaviour of 'return' per 1 above.

This commit fixes both issues. It also takes a proper decision on
allowable 'return' exit status arguments. Since 93u+ was released
nearly a decade ago and some scripts may now rely on being able to
pass certain exit statuses out of the 8-bit range, we should not
disallow this now. But neither should we be half-hearted in
allowing only some arbitrary selection of 9-bit statuses; 'return'
values categorically should have nothing to do with signals, so
this is no basis for limiting them. We're now allowing the full
unsigned integer range, which is usually 32 bits. This is like zsh,
and may create some interesting possibilities for scripts.
Just don't forget that $? will still lose all but its 8 least
significant bits when leaving the current (sub)shell environment.

src/cmd/ksh93/sh/xec.c: sh_funscope():
- Fix passing down unhandled signals from interrupted ksh functions
  (jumpval==SH_JMPFUN) to the parent environment. Do not pay any
  attention to the exit status. Instead, use sh.lastsig (a.k.a.
  shp->lastsig). It is set by sh_fault() in fault.c for just this
  purpose and contains the last signal handled for the current
  command. It is reset in sh_exec() before running any new command.
  So if it contains a signal, that is the one that interrupted the
  ksh function, so it's the correct one to pass down. (Further
  evidence: sh_subshell() was already using this in the same way.)

src/cmd/ksh93/bltins/cflow.c: b_return():
- Allow any signed int return value when invoked as and behaving
  like 'return'.
- Add warning if a passed value is out of int range. Set the exit
  status to 128 in that case; int overflow is undefined behaviour
  in C and we want consistent behaviour across platforms. It should
  be safe enough to check if the long and int values are equal.
- Refactor for clarity.

src/cmd/ksh93/sh/subshell.c: sh_subshell():
- If a function returns with a status out of the 8 bit range in a
  virtual subshell, this status could be passed down to the parent
  shell in full. However, if the subshell forks, then the kernel
  will enforce an 8-bit exit status. That is inconsistent. Scripts
  should not be able to tell the difference between forked and
  non-forked subshells, so artificially enforce that limit here.

Other changed files:
- Documentation updates and copy-edits.
- Update an AT&T functions.sh regress test to allow arbitrary
  integer return values for functions.
- Add regression tests based in part on @JohnoKing's reproducers.
- Rework some vaguely related regression tests to fail gracefully.

Thanks to Johnothan King for the report and the testing.

Fixes: https://github.com/ksh93/ksh/issues/364
2021-12-09 06:41:39 +01:00
..
bltins Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
data Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
edit Fix `KEYBD` trap crash when inputting a command substitution (#355) 2021-11-30 04:27:31 +01:00
features Fix typeset -u/-l on NetBSD 2021-05-18 18:26:33 +02:00
fun
include Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
sh Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
tests Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
COMPATIBILITY Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
DESIGN manual: use consistent terminology 2021-11-19 03:54:42 +01:00
Mamfile Fix $RANDOM to act consistently in subshells (#294) 2021-05-03 04:03:46 +01:00
OBSOLETE Fix many spelling errors and word repetitions (#188) 2021-02-20 03:22:24 +00:00
PROMO.mm manual: use consistent terminology 2021-11-19 03:54:42 +01:00
README Fix memory fault on ARM-based Macs (#354) 2021-11-29 20:12:57 +01:00
RELEASE fix 3 typos: staring -> starting 2021-11-09 13:52:08 +00:00
RELEASE88 Release 1.0.0-beta.1 2021-05-10 18:42:42 +02:00
RELEASE93 Release 1.0.0-beta.1 2021-05-10 18:42:42 +02:00
SHOPT.sh Disable SHOPT_EDPREDICT compile-time option by default 2021-04-22 17:37:12 +01:00
TYPES Allow proper tilde expansion overrides (#225) 2021-03-17 21:07:14 +00:00
builtins.mm Fix more compiler warnings, typos and other minor issues (#260) 2021-04-08 19:58:07 +01:00
ksh-regress.rt
ksh-regress.tst
mamexec Fix various minor problems and update the documentation (#237) 2021-03-21 14:39:03 +00:00
mamstate.c Add ksh 93u+m contributors notice to 964 copyright headers 2021-04-26 00:19:31 +01:00
nval.3 Lots of man page fixes and some other minor fixes (#284) 2021-04-23 22:02:30 +01:00
sh.1 Fix 'return' emitting signals; allow arbitrary return values 2021-12-09 06:41:39 +01:00
sh.memo Fix more compiler warnings, typos and other minor issues (#260) 2021-04-08 19:58:07 +01:00
shell.3 shell.3: fix formatting for sh_{g,s}etscope 2021-11-20 04:53:42 +01:00

README

This directory, and its subdirectories contain the source code
for ksh-93; the language described in the second addition of
the book, "The KornShell Command and Programming Language," by
Morris Bolsky and David Korn which is published by Prentice Hall.
ksh-93 has been compiled and run on several machines with several
operating systems.  The end of this file contains a partial list of
operating systems and machines that ksh-93 has been known to run on.

Most of the source code for ksh is in the src/cmd/ksh93/sh
directory. For information on what's where, see the file DESIGN.

#### COMPILE-TIME OPTIONS ####

The SHOPT.sh file contains several compilation options that can be set
before compiling ksh.  Options are of the form SHOPT_option and become
#define inside the code.  These options are set to their recommended
value and some of these may disappear as options in future releases.
A value of 0 represents off, 1 represents on, no value means probe. For
options where no feature probe is available, probe is the same as off.

The options have the following defaults and meanings:

    2DMATCH      on  Two-dimensional ${.sh.match} for ${var//pat/str}.

    ACCT         off Shell accounting.

    ACCTFILE     off Enable per user accounting info.

    AUDIT	 off For auditing specific users

    AUDITFILE	 "/etc/ksh_audit"

    BGX          on  Enables background job extensions. Noted by "J" in the
                     version string when enabled. (1) JOBMAX=n limits the
                     number of concurrent background jobs to n; the (n+1)th
                     background job will block until a running background job
                     completes. (2) SIGCHLD traps are queued so that each
                     completing background job gets its own trap; $! is set to
                     the job pid and $? is set to the job exit status at the
                     beginning of the trap.

    BRACEPAT     on  Brace expansion. Expands abc{d,e}f to abcdf abcef.
                     This feature was inspired by the C shell.

    CMDLIB_HDR   "<cmdlist.h>"
                     The header in which you can provide a custom list of
                     libcmd commands to provide as path-bound built-ins.

    CMDLIB_DIR   "\"/opt/ast/bin\""
                     The default virtual directory prefix for path-bound
                     built-ins. The value must include double quotes.

    CRNL         off <cr><nl> treated as <nl> in shell grammar.

    DEVFD            Use the more secure /dev/fd mechanism instead of FIFOs for
                     process substitutions. On by default on OSs with /dev/fd.

    DYNAMIC      on  Dynamic loading of builtins. (Requires dlopen() interface.)

    ECHOPRINT    off Make echo equivalent to print.

    EDPREDICT    off Enables history pattern search menu. As you begin a line
                     with a #, the following characters are treated as a shell
                     pattern and cause matching lines from the history file to
                     be displayed as a numbered list as you type. You can
                     scroll up and down this list or you can use <ESC>nTAB to
                     make this the current line (n defaults to 1 if omitted).
                     Experimental. Bugs: https://github.com/ksh93/ksh/issues/233

    ESH          on  Compile with emacs command line editing.  The original
                     emacs line editor code was provided by Mike Veach at IH.

    FILESCAN     on  Experimental option that allows fast reading of files
                     using while < file;do ...; done and allowing fields in
                     each line to be accessed as positional parameters.

    FIXEDARRAY   on  When using typeset, a name in the format NAME[N]
                     creates a fixed-size array and any attempt to access a
                     subscript N or higher is an error. Multidimensional
                     fixed-size arrays NAME[N1][N2]... are also supported.

    GLOBCASEDET      Adds the 'globcasedetect' shell option. When this shell
                     option is turned on, pathname expansion (globbing)
                     and file name listing and completion automatically become
                     case-insensitive on file systems where the difference
                     between upper- and lowercase is ignored for file names.
                     This compile-time option is enabled by default on operating
                     systems that can support case-insensitive file systems.

    HISTEXPAND   on  Enable !-style history expansion similar to csh(1).

    KIA          off Allow generation of shell cross reference database with -R.
                     As of 2021-05-10, no tool that can parse this database is
                     known. If you know of any, please contact us.

    MULTIBYTE    on  Multibyte character handling.  Requires mblen() and
                     mbctowc().

    NAMESPACE    on  Adds a 'namespace' reserved word that allows defining name
                     spaces. Variables and functions defined within a block like
                        namespace ExampleSpace { commandlist; }
                     all have their names automatically prefixed with
                     '.ExampleSpace.' when defining or using them, creating a
                     separate space of names unique to the block. Outside of
                     the namespace block, they can be accessed using
                     .ExampleSpace.function or ${.ExampleSpace.variable}.
                     Name spaces within name spaces are also supported.

    NOECHOE      off Disable the '-e' option to the 'echo' command,
                     unless SHOPT_ECHOPRINT is enabled.

    OLDTERMIO    off Use either termios or termio at runtime.

    OPTIMIZE     on  Optimize loop invariants for with for and while loops.

    PFSH         off Compile with support for profile shell. (Solaris; obsolete)

    P_SUID       off If set, all real uids, greater than or equal to this
                     value will require the -p flag to run suid/sgid scripts.

    RAWONLY      on  Turn on if the vi line mode doesn't work right unless
                     you do a set -o viraw.

    REGRESS      off Enable the __regress__ built-in command and instrumented
                     intercepts for testing.

    REMOTE       off Set --rc (read profile scripts) even if ksh was invoked
                     with standard input on a socket, i.e. as a remote shell.

    SPAWN        on  Use posix_spawn(3) as combined fork/exec if job control
                     is not active. Improves speed.

    STATS	 on  Add .sh.stats compound variable.

    SUID_EXEC    on  Execute /etc/suid_exec for setuid, setgid script.

    SYSRC            Source /etc/ksh.kshrc on initializing an interactive
                     shell. This is on by default if /etc/ksh.kshrc or
                     /etc/bash.bashrc exists at compile time.

    TEST_L           Add 'test -l' as an alias for 'test -L'. This is on by
                     default if the OS's external 'test' command supports it.

    TIMEOUT      off Set this to the number of seconds for timing out and
                     exiting the shell when you don't enter a command.  If
                     non-zero, TMOUT can not be set larger than this value.

    TYPEDEF	 on  Enable typeset type definitions.

    VSH          on  Compile with vi command line editing.  The original vi
                     line editor code was provided by Pat Sullivan at CB.

#### BUILDING KSH 93U+M ####

To build ksh (as well as libcmd and libast libraries on which ksh depends),
cd to the top directory and run:

	bin/package make

The compiled binaries are stored in the arch directory, in a subdirectory
that corresponds to your architecture. The command 'bin/package host type'
outputs the name of this subdirectory.

If you have trouble or want to tune the binaries, you may pass additional
compiler and linker flags. It is usually best to export these as environment
variables before running bin/package as they could change the name of the
build subdirectory of the arch directory, so exporting them is a convenient
way to keep them consistent between build and test commands. Note that this
system uses CCFLAGS instead of the usual CFLAGS. An example that makes
Solaris Studio cc produce a 64-bit binary:

	export CCFLAGS="-m64 -O" LDFLAGS="-m64"
	bin/package make

Alternatively you can append these to the command, and they will only be
used for that command. You can also specify an alternative shell in which to
run the build scripts this way. For example:

	bin/package make SHELL=/bin/bash CCFLAGS="-O2 -I/opt/local/include" \
		LDFLAGS="-L/opt/local/lib"

For more information, run:

	bin/package help

Many other commands in this repo self-document via the --help, --man and
--html options; those that do have no separate manual page.

Automated installation is not supported yet. To install manually:

	cp arch/$(bin/package host type)/bin/ksh /usr/local/bin/
	cp src/cmd/ksh93/sh.1 /usr/local/share/man/man1/ksh.1

(adapting the destination directories as required).

The build should also generate shcomp, a program that will precompile
a script.  ksh93 is able to recognize files in this format and process
them as scripts.  You can use shcomp to send out scripts when you
don't want to give away the original script source.

To be able to run setuid/setgid shell scripts, or scripts without read
permission, the SUID_EXEC compile option must be on, and ksh must be installed
in the /bin directory, the /usr/bin directory, the /usr/lbin directory,
or the /usr/local/bin directory and the name must end in sh. The program
suid_exec must be installed in the /etc directory, must be owned by root,
and must be a suid program.  If you must install ksh in some other directory
and want to be able to run setuid/setgid and execute only scripts, then
you will have to change the source code file sh/suid_exec.c explicitly.
If you do not have ksh in one of these secure locations, /bin/sh will
be invoked with the -p options and will fail when you execute a setuid/setgid
and/or execute only script.  Note, that ksh does not read the .profile
or $ENV file when it the real and effective user/group id's are not
equal.

#### TESTING KSH ####

The tests subdirectory contains a number of regression tests for ksh.
To run all these tests with the shell you just built, run the command
	bin/shtests
For help and more options, type
	bin/shtests --man

#### OTHER DOCUMENTATION ####

The file PROMO.mm is an advertisement that extolls the virtues of ksh.
The file sh.1 contains the troff (man) description of this Shell.
The file nval.3 contains the troff (man) description of the name-value
pair library that is needed for writing built-ins that need to
access shell variables.

The file sh.memo contains a draft troff (mm) memo describing ksh.  The
file builtins.mm is a draft troff (mm) memo describing how to write
built-in commands that can be loaded at run time.

The file NEWS in the top-level directory contains bug fixes and other
changes made in the ksh 93u+m fork and supporting libraries.  The file
COMPATIBILITY contains a list of potential incompatibilities.

#### TESTED SYSTEMS ####

ksh 93u+m 1.0.0.beta-1 has been compiled and tested on the following.
An asterisk signifies minor regression test failures (one or two minor
things amiss), two asterisks signify moderate regression test failures
(some functionality does not work), and three asterisks signify serious
failures (crashes, and/or important functionality does not work).

*	AIX 7.1 on RISC (PowerPC)
*	DragonFly BSD 5.8 on x86_64
	FreeBSD 12.2 on x86_64
	FreeBSD 12.2 on arm64 (thanks to hyenias for donating access to a Pi)
	GNU/Linux: Alpine 3.12.3 (musl C library) on x86_64
	GNU/Linux: CentOS 8.2 on x86_64
	GNU/Linux: Debian 10.7 on x86_64
	GNU/Linux: Gentoo 2.7 on i386
	GNU/Linux: NixOS 19.09 on x86_64
	GNU/Linux: Slackware 14.2 on x86_64
	GNU/Linux: Ubuntu 16.04 on x86_64
	GNU/Linux: Ubuntu 18.04 on armv7l (32-bit)
	GNU/Linux: Ubuntu 20.04 on aarch64
	GNU/Linux: Void Linux (musl C library) on x86_64
***	HP-UX B.11.11 on pa-risc
*	illumos: OmniOS 2020-08-19 (gcc) on x86_64
	macOS 10.13.6 (High Sierra) on x86_64
	macOS 10.14.6 (Mojave) on x86_64
*	macOS 12.0.1 (Monterey) on ARM64
*	NetBSD 8.1 on x86_64
*	NetBSD 9.2 on x86_64
*	OpenBSD 6.8 on x86_64
**	QNX 6.5.0 on i386
*	Solaris 11.4 (gcc) on x86_64
	Solaris 11.4 (Solaris Studio 12.5 cc) on x86_64
*	UnixWare 7.1.4 on x86
***	Windows 7 using Cygwin on x86

#### REPORTING BUGS ####

Please report any problems or suggestions by opening an issue at:
https://github.com/ksh93/ksh
Alternatively, email martijn@inlv.org (timely response *not* promised).

Good luck!!

The ksh 93u+m contributors
https://github.com/ksh93/ksh

Originally written by:
David Korn
dgk@research.att.com