ksh: Freeze/crash on OpenBSD with `-D_std_malloc` involving `typeset` and command substitution

The regression tests added in #239 freeze on OpenBSD when ksh is compiled with -D_std_malloc (I’ve reproduced this bug in a virtual machine). Reproducer:

$ bin/shtests -p readonly
# Freezes

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 46

Commits related to this issue

Most upvoted comments

I’ll note that I just tested the test script under ASan and it no longer crashes with a heap-use-after-free error. Combined with the fact it now works correctly on OpenBSD 7.0, I don’t see much reason to leave this issue open.

/etc/ksh.kshrc on OpenBSD uses local. If you change that to typeset, it works on ksh93 too.

There is a bug in ksh that causes this regression test to freeze on OpenBSD. Changing the test to avoid the freeze does nothing to fix that bug, it’ll only hide it.

This may be okay, especially since I’m trying to get a beta out soon. But it will also lead to that bug being forgotten.

So, before I commit any workaround (other than the one I committed that allows the tests to fail gracefully on older ksh versions), I’d like to have an independent reproducer for the freeze that can be used to file a new bug, so that there is a chance that freeze will actually be fixed sometime.

Note 1 There appears to be a parsing issue with (( during a command substitution with a compound array assignment. Notice below when a space is used to break apart the double left parentheses, parsing works and the array is created.

$ arch/*/bin/ksh -c 'got=$( typeset -a arr=((a b c) 1); readonly arr; typeset -p arr ); echo $got'
arch/linux.i386-64/bin/ksh: syntax error at line 1: `(' unmatched
$ arch/*/bin/ksh -c 'got=$( typeset -a arr=( (a b c) 1); readonly arr; typeset -p arr ); echo $got'
typeset -r -a arr=((a b c) 1)

Command subshells do not have this issue:

$ arch/*/bin/ksh -c '( typeset -a arr=((a b c) 1); readonly arr; typeset -p arr )'
typeset -r -a arr=((a b c) 1)
$ arch/*/bin/ksh -c '( typeset -a arr=( (a b c) 1); readonly arr; typeset -p arr )'
typeset -r -a arr=((a b c) 1)