msuozzo opened PR #14663 from msuozzo:push-zpzysumusmtl to bytecodealliance:main:
With a trailing slash,
remove_dirresolved a symlink to its target
directory and then tried to remove.there, failing with EINVAL
(EACCES on Windows). Linux fails with ENOTDIR instead, since rmdir
never removes a directory through a symlink, while macOS and FreeBSD
remove the target and leave the symlink dangling. Follow Linux: it's
the more conservative choice, and the one applications most likely
expect.The symlink is still resolved within the preopen first, so one that
escapes, dangles or names a file fails as before. FreeBSD's
unlinkat(RESOLVE_BENEATH)fast path now skips trailing slashes, since
that kernel removes the target.
msuozzo requested rvolosatovs for a review on PR #14663.
msuozzo requested wasmtime-wasi-reviewers for a review on PR #14663.
msuozzo requested dicej for a review on PR #14663.
msuozzo requested wasmtime-core-reviewers for a review on PR #14663.
msuozzo edited PR #14663:
With a trailing slash,
remove_dirresolved a symlink to its target
directory and then tried to remove.there, failing with EINVAL
(EACCES on Windows). Linux fails with ENOTDIR instead, since rmdir
never removes a directory through a symlink, while macOS and FreeBSD
remove the target and leave the symlink dangling. Follow Linux: it's
the more conservative choice, and the one applications most likely
expect.The symlink is still resolved within the preopen first, so one that
escapes, dangles or names a file fails as before. FreeBSD's
unlinkat(RESOLVE_BENEATH)fast path now skips trailing slashes, since
that kernel removes the target.Parents: #14662
github-actions[bot] added the label wasi on PR #14663.
:memo: rvolosatovs submitted PR review:
Looks good overall, just one question. Also, could you rebase on latest
main, there's a merge conflict now that https://github.com/bytecodealliance/wasmtime/pull/14662 is merged
:speech_balloon: rvolosatovs created PR review comment:
Since we're trying to match Linux here, should we just drop this line?
AFAIK, Linux returns ENOTDIR in these cases
msuozzo updated PR #14663.
msuozzo edited PR #14663:
With a trailing slash,
remove_dirresolved a symlink to its target
directory and then tried to remove.there, failing with EINVAL
(EACCES on Windows). Linux fails with ENOTDIR instead, since rmdir
never removes a directory through a symlink, while macOS and FreeBSD
remove the target and leave the symlink dangling. Follow Linux: it's
the more conservative choice, and the one applications most likely
expect.The symlink is still resolved within the preopen first, so one that
escapes, dangles or names a file fails as before. FreeBSD's
unlinkat(RESOLVE_BENEATH)fast path now skips trailing slashes, since
that kernel removes the target.
:memo: msuozzo submitted PR review.
:speech_balloon: msuozzo created PR review comment:
Yeah, makes sense. I checked on Linux, and rmdir gives ENOTDIR for a symlink with a trailing slash no matter what it points to (a directory, a file, nothing,
..or/). It never touches the target. I'll drop the line.One knock-on effect: upstream wasi-testsuite asserts that
rmdir("parent.cleanup/")is NotPermitted, whereparent.cleanuplinks to... This behavior to remove the underlying dir does appear to match a strict reading of POSIX and is the same behavior macOS uses. Still, I think it's pretty obviously bad to leave the symlink broken which would also be required by this reading (and is what macOS implements).With this change it's NotDirectory instead, like Linux. I'll send a PR to wasi-testsuite to accept either, so the next submodule bump doesn't break. Happy to make the test require NotDirectory if you'd prefer but allowing POSIX feels prudent.
:speech_balloon: msuozzo edited PR review comment.
msuozzo updated PR #14663.
msuozzo edited PR #14663:
With a trailing slash,
remove_dirresolved a symlink to its target
directory and then tried to remove.there, failing with EINVAL
(EACCES on Windows). Linux fails with ENOTDIR instead, since rmdir
never removes a directory through a symlink, while macOS and FreeBSD
remove the target and leave the symlink dangling. Follow Linux: it's
the more conservative choice, and the one applications most likely
expect.The symlink isn't followed, so a link that dangles or leads outside the
preopen now fails with ENOTDIR too, where it failed with ENOENT or EPERM
before. FreeBSD'sunlinkat(RESOLVE_BENEATH)fast path now skips
trailing slashes, since that kernel removes the target.Upstream wasi-testsuite still expects
NotPermittedfor a link leading
outside the preopen. WebAssembly/wasi-testsuite#292 relaxes that.
msuozzo updated PR #14663.
msuozzo edited PR #14663:
With a trailing slash,
remove_dirresolved a symlink to its target
directory and then tried to remove.there, failing with EINVAL
(EACCES on Windows). Linux fails with ENOTDIR instead, since rmdir
never removes a directory through a symlink, while macOS and FreeBSD
remove the target and leave the symlink dangling. Follow Linux: it's
the more conservative choice, and the one applications most likely
expect.The symlink isn't followed, so a link that dangles or leads outside the
preopen now fails with ENOTDIR too, where it failed with ENOENT or EPERM
before. FreeBSD'sunlinkat(RESOLVE_BENEATH)fast path now skips
trailing slashes, since that kernel removes the target.prtest:full
Upstream wasi-testsuite still expects
NotPermittedfor a link leading
outside the preopen. WebAssembly/wasi-testsuite#292 relaxes that.
:memo: msuozzo submitted PR review.
:speech_balloon: msuozzo created PR review comment:
okay opened WebAssembly/wasi-testsuitez#292 with the test update
:speech_balloon: msuozzo edited PR review comment.
msuozzo updated PR #14663.
:memo: rvolosatovs submitted PR review.
:speech_balloon: rvolosatovs created PR review comment:
Awesome, thanks!
:thumbs_up: rvolosatovs submitted PR review.
rvolosatovs has enabled auto merge for PR #14663.
rvolosatovs added PR #14663 wasi: refuse to rmdir through a symlink with a trailing slash to the merge queue.
:check: rvolosatovs merged PR #14663.
rvolosatovs removed PR #14663 wasi: refuse to rmdir through a symlink with a trailing slash from the merge queue.
Last updated: Oct 31 2026 at 23:03 UTC