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

Proper emulation of magic symlinks (e.g. in procfs) #1872

Open
mkow opened this issue May 7, 2024 · 2 comments
Open

Proper emulation of magic symlinks (e.g. in procfs) #1872

mkow opened this issue May 7, 2024 · 2 comments

Comments

@mkow
Copy link
Member

mkow commented May 7, 2024

Description of the problem

Some symlinks on Linux FS are not really symlinks, and we have to emulate that properly.

Example: a pipe in /proc/self/fd/XX pretends to be a symlink (file type is S_IFLNK), but readlink returns a string in form of pipe:[29335264]. Despite this, it's still possible to open this file on Linux, but following it as a symlink is impossible.

Currently in Gramine we return those weird strings via readlink(), but when trying to open them our path resolver tries to follow them, thus failing to open the file.

We probably need a new type of dentry for these fake links, or some special flag which would prevent the path resolver from following them.

// This is a split-out from #1267.

Steps to reproduce

Run cat some_file | cat /proc/self/fd/0 in Bash under Gramine.

Expected results

<some_file contents>

Actual results

cat: /proc/self/fd/0: No such file or directory printed to stderr.

Gramine commit hash

64cd864

@dimakuv
Copy link

dimakuv commented May 7, 2024

Currently in Gramine we return those weird strings via readlink()

In particular, this code does it:

* Human-readable string for a handle without attached dentry.
*
* TODO: Linux uses names like `pipe:[INODE]`, we could at least include more information whenever
* we can (e.g. socket address).
*/
static char* describe_handle(struct libos_handle* hdl) {
const char* str;
switch (hdl->type) {
case TYPE_CHROOT: str = "chroot:[?]"; break;
case TYPE_DEV: str = "dev:[?]"; break;
case TYPE_STR: str = "str:[?]"; break;
case TYPE_PSEUDO: str = "pseudo:[?]"; break;
case TYPE_PIPE: str = "pipe:[?]"; break;
case TYPE_SOCK: str = "sock:[?]"; break;
case TYPE_EPOLL: str = "epoll:[?]"; break;
case TYPE_EVENTFD: str = "eventfd:[?]"; break;
case TYPE_SHM: str = "shm:[?]"; break;
default: str = "unknown:[?]"; break;
}
return strdup(str);
}

However, there is no inode information, just a hard-coded [?]. That's not ideal; but probably real-world apps don't care and don't use the inode numbers like this.

We probably need a new type of dentry for these fake links, or some special flag which would prevent the path resolver from following them.

I am afraid we'll have to introduce proper dentry objects for these (well, without any real path, but still pointing to a valid inode). Otherwise this will become full of special cases. At the same time, this will probably a big change, and I'd say it's not worth it unless we have a real app (that cannot circumvent this limitation).

@dimakuv
Copy link

dimakuv commented May 7, 2024

At the same time, this will probably a big change, and I'd say it's not worth it unless we have a real app (that cannot circumvent this limitation).

I take my words back. We already have such an application, and it is Bash: #1267

So maybe implementing it should be a higher priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants