Fix preopen path traversal in WASI 0.2 descriptor.open-at - #466
Conversation
fc087c0 to
ed4e84f
Compare
| return false; | ||
| } | ||
|
|
||
| std::vector<std::string> parsedComponents; |
There was a problem hiding this comment.
Do we need to duplicate these strings? Could we use substrings for this purpose?
| path.append(componentPath); | ||
|
|
||
| // uv_fs_t req; | ||
| // int descriptor = uv_fs_open(NULL, &req, path.c_str(), openFlags, 0666, NULL); |
There was a problem hiding this comment.
I am unsure about changing these functions. We use libuv and uvwasi for maximum portability between platforms as it supports both windows and linux. Dealing directly with system calls might introduce lots of things to maintain.
I think only implementing correct path resolution would be sufficient enough.
There was a problem hiding this comment.
I understand that libuv doesn’t provide an openat()-style API for resolving paths relative to a directory FD.
Following your suggestion, I could use uv_fs_realpath() to resolve the path, verify that it remains within the preopen directory, and then open it with uv_fs_open(). However, I think this approach could introduce a TOCTOU vulnerability if the path or a symbolic link changes between the resolution and open operations.
Would this limitation be acceptable here, or is there another mechanism in uvwasi that should be used to avoid it?
There was a problem hiding this comment.
The wasi 0.1 implementation uses this code:
https://github.com/nodejs/uvwasi/blob/main/src/path_resolver.c#L417
It is partly custom, partly uw. Would be good if we could use only one code path, but this might be too difficult.
There was a problem hiding this comment.
Thanks. I will try reusing uvwasi__resolve_path() by resolving the WASI 0.2 guest path one component at a time, then passing the final resolved path to uv_fs_open().
Since uvwasi__resolve_path() is an internal uvwasi API,, would it be acceptable to include it in WASI.cpp, for example:
extern "C" {
#include "../../third_party/uvwasi/uvwasi/src/path_resolver.h"
}There was a problem hiding this comment.
Well it should work in theory. @ksh8281 what do you think? Is this kind of include acceptable?
7d09bbb to
d3def34
Compare
|
I updated CMake so that the uvwasi internal headers can be included without using relative include paths. |
818cfbd to
f518131
Compare
f518131 to
b69069d
Compare
Fixes a path traversal issue in WASI 0.2
descriptor.open-at.Fix
Prevents
..and symbolic links from escaping the preopen boundary.Note
The Unix implementation uses
openat()andreadlinkat()and is still being completed.Windows support will be implemented separately.
Progress
Completed
..from escaping the preopen rootopenat()readlinkat()Remaining
./..handling and trailing-slash semantics