Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scope variables to their subshell before assigning their discipline #811

Merged
merged 4 commits into from
Jan 5, 2025

Conversation

JohnoKing
Copy link

Currently, running the tilde.sh tests under ASan will fail with a use after free. Stacktrace below (with irrelevant parts cut out):

test tilde(C.UTF-8) begins at 2024-12-28+20:08:53
================================================================= ==189441==ERROR: AddressSanitizer: heap-use-after-free on address 0x5070000069a8 at pc 0x7b65d030bd77 bp 0x7ffc12db7390 sp 0x7ffc12db7380 READ of size 2 at 0x5070000069a8 thread T0
    #0 0x7b65d030bd76 in simple /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:1484
    #1 0x7b65d030a209 in item /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:1374
    #2 0x7b65d02fc516 in term /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:655
    ---CUT 1---

0x5070000069a8 is located 24 bytes inside of 78-byte region [0x507000006990,0x5070000069de) freed by thread T0 here:
    #0 0x7b65d0d53ef2 in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x7b65d02bd246 in nv_delete /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/name.c:1329
    #2 0x7b65d03621d3 in sh_subshell /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/subshell.c:807
    #3 0x7b65d029902b in comsubst /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/macro.c:2268
    ---CUT 2---

previously allocated by thread T0 here:
    #0 0x7b65d0d555da in calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
    #1 0x7b65d01dd012 in sh_calloc /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/init.c:255
    #2 0x7b65d0135140 in newnode /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/nvdisc.c:823
    #3 0x7b65d0138da4 in nv_search /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/nvdisc.c:1022
    #4 0x7b65d02c0552 in nv_open /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/name.c:1486
    #5 0x7b65d039d356 in sh_exec /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/xec.c:2484
    ---CUT 3---

The crash occurs because the discipline function is assigned before .sh.tilde is scoped to the currently active virtual subshell. After this, sh_subshell frees the discipline function by calling nv_delete upon subshell completion, but because of improper scoping .sh.tilde in the parent subshell now has an np->nvfun which points to freed memory. (As a side note, I'll note that this bug can be reproduced for any variable assigned a discipline function, not just .sh.tilde.)

src/cmd/ksh93/sh/xec.c: sh_exec():

  • Use sh_assignok to scope variables to subshells before assigning a new discipline function to them.

Currently, running the tilde.sh tests under ASan will fail with a
use after free. Stacktrace below (with irrelevant parts cut out):
test tilde(C.UTF-8) begins at 2024-12-28+20:08:53
=================================================================
==189441==ERROR: AddressSanitizer: heap-use-after-free on address 0x5070000069a8 at pc 0x7b65d030bd77 bp 0x7ffc12db7390 sp 0x7ffc12db7380
READ of size 2 at 0x5070000069a8 thread T0
    #0 0x7b65d030bd76 in simple /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:1484
    ksh93#1 0x7b65d030a209 in item /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:1374
    ksh93#2 0x7b65d02fc516 in term /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/parse.c:655
    ---CUT 1---

0x5070000069a8 is located 24 bytes inside of 78-byte region [0x507000006990,0x5070000069de)
freed by thread T0 here:
    #0 0x7b65d0d53ef2 in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    ksh93#1 0x7b65d02bd246 in nv_delete /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/name.c:1329
    ksh93#2 0x7b65d03621d3 in sh_subshell /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/subshell.c:807
    ksh93#3 0x7b65d029902b in comsubst /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/macro.c:2268
    ---CUT 2---

previously allocated by thread T0 here:
    #0 0x7b65d0d555da in calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
    ksh93#1 0x7b65d01dd012 in sh_calloc /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/init.c:255
    ksh93#2 0x7b65d0135140 in newnode /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/nvdisc.c:823
    ksh93#3 0x7b65d0138da4 in nv_search /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/nvdisc.c:1022
    ksh93#4 0x7b65d02c0552 in nv_open /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/name.c:1486
    ksh93#5 0x7b65d039d356 in sh_exec /home/johno/GitRepos/KornShell/ksh/src/cmd/ksh93/sh/xec.c:2484
    ---CUT 3---

The crash occurs because the discipline function is assigned
before .sh.tilde is scoped to the currently active virtual subshell.
After this, sh_subshell frees the discipline function by calling
nv_delete upon subshell completion, but because of improper scoping
.sh.tilde in the parent subshell now has an np->nvfun which points to
freed memory. (As a side note, I'll note that this bug can be reproduced
for any variable assigned a discipline function, not just .sh.tilde.)

src/cmd/ksh93/sh/xec.c: sh_exec():
- Use sh_assignok to scope variables to subshells before assigning
  a new discipline function to them.
@JohnoKing JohnoKing changed the title Scope variables to their subshell before running their discipline Scope variables to their subshell before assigning their discipline Dec 29, 2024
@McDutchie
Copy link

That's well analysed, thanks for finding the fix. This one has been bugging me for ages.

@McDutchie McDutchie force-pushed the fix-tilde-discipline-use-after-free branch from cc1fb49 to b4d411c Compare January 5, 2025 02:48
@McDutchie McDutchie merged commit cbdb8bc into ksh93:dev Jan 5, 2025
McDutchie pushed a commit that referenced this pull request Jan 5, 2025
Currently, running the tilde.sh tests under ASan will fail with a
use after free.

The crash occurs because the discipline function is assigned before
.sh.tilde is scoped to the currently active virtual subshell. After
this, sh_subshell() frees the discipline function by calling
nv_delete() upon subshell completion, but because of improper
scoping, .sh.tilde in the parent subshell now has an np->nvfun
which points to freed memory. (As a side note, I'll note that this
bug can be reproduced for any variable assigned a discipline
function, not just .sh.tilde.)

src/cmd/ksh93/sh/xec.c: sh_exec():
- Use sh_assignok to scope variables to subshells before assigning
  a new discipline function to them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants