-
Notifications
You must be signed in to change notification settings - Fork 268
fstatat and similar syscalls return wrong value when path name is empty #3659
Description
When a plugin process calls fstatat with an empty path, shadow returns 0 instead of -ENOENT.
For example, in an Ubuntu 25.04 container:
$ /usr/bin/sh -c '[ ! -d "" ] && echo true || echo false'
true
$ shadow-exec -- /usr/bin/sh -c '[ ! -d "" ] && echo true || echo false'
falseThe reason is that Shadow's fstatat syscall handler, if an fd of AT_FDCWD is given, appends the path to the cwd and calls the native fstatat on that path instead. So for the simulated syscall fstatat(AT_FDCWD, "", ...), shadow will actually call fstatat(-1, "/path/to/cwd", ...). But the man page for fstatat says:
ENOENT
pathname is an empty string and AT_EMPTY_PATH was not specified in flags.
So while the syscall fstatat(AT_FDCWD, "", ...) would normally fail with ENOENT, in Shadow it instead returns 0 since the pathname is not an empty string.
I believe that this is also applicable to the other -at syscall handlers, but I haven't checked this in-depth yet.
This breaks the following common pattern in bash scripts:
if [ ! -d "$DIR" ]; then
DIR="/tmp"
fi