Skip to content

fstatat and similar syscalls return wrong value when path name is empty #3659

@stevenengler

Description

@stevenengler

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'
false

The 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: BugError or flaw producing unexpected results

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions