Browse Source

Update to libpreopen 8835639f27fc42d32096d59d294a0bbb857dc368.

This replaces our custom `unlink` wrapper with an upstream one. We still
end up replacing the entire body with local changes, but this makes it
easier to see what those changes are.

The other change here is a fix to ignore repeated '/'s in paths.
pull/63/head
Dan Gohman 6 years ago
parent
commit
a077330632
  1. 2
      libc-bottom-half/README.md
  2. 2
      libc-bottom-half/libpreopen/lib/libpreopen.c
  3. 52
      libc-bottom-half/libpreopen/lib/po_libc_wrappers.c

2
libc-bottom-half/README.md

@ -14,7 +14,7 @@ libpreopen, and we have several customizations for use in a WebAssembly sysroot.
The upstream repositories and versions used here are:
cloudlibc - https://github.com/NuxiNL/cloudlibc 8835639f27fc42d32096d59d294a0bbb857dc368
libpreopen - https://github.com/musec/libpreopen 8265fc50b9db3730c250597bdd084f1e728f3e48
libpreopen - https://github.com/musec/libpreopen b29e9287cc75a7db7291ce3eb468a3d2bad8ceb1
Whole files which are unused are omitted. Changes to upstream code are wrapped
in preprocessor directives controlled by the macro `__wasilibc_unmodified_upstream`,

2
libc-bottom-half/libpreopen/lib/libpreopen.c

@ -174,7 +174,7 @@ po_find(struct po_map* map, const char *path,
relpath = path + bestlen;
if (*relpath == '/') {
while (*relpath == '/') {
relpath++;
}

52
libc-bottom-half/libpreopen/lib/po_libc_wrappers.c

@ -369,6 +369,43 @@ stat(const char *path, struct stat *st)
return fstatat(rel.dirfd, rel.relative_path,st, AT_SYMLINK_NOFOLLOW);
}
/**
* Capability-safe wrapper around the `unlink(2)` system call.
*
* `unlink(2)` accepts a path argument that can reference the global filesystem
* namespace. This is not a capability-safe operation, so this wrapper function
* attempts to look up the path (or a prefix of it) within the current global
* po_map and converts the call into the capability-safe `unlinkat(2)` if
* possible. If the current po_map does not contain the sought-after path,
* this wrapper will call `unlinkat(AT_FDCWD, original_path, 0) which is
* the same as the unwrapped `unlink(2)` call (i.e., will fail with `ECAPMODE`).
*/
int
unlink(const char *path)
{
#ifdef __wasilibc_unmodified_upstream
struct po_relpath rel = find_relative(path, NULL);
#else
struct po_relpath rel_pathname = find_relative(path, __WASI_RIGHT_PATH_UNLINK_FILE, 0);
// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
if (rel_pathname.dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
#endif
#ifdef __wasilibc_unmodified_upstream
return unlinkat(rel.dirfd, rel.relative_path, 0);
#else
// `unlinkat` ends up importing `__wasi_path_remove_directory` even
// though we're not passing `AT_REMOVEDIR` here. So instead, use a
// specialized function which just imports `__wasi_path_unlink_file`.
return __wasilibc_unlinkat(rel_pathname.dirfd, rel_pathname.relative_path);
#endif
}
/*
* Wrappers around other libc calls:
*/
@ -397,21 +434,6 @@ dlopen(const char *path, int mode)
#else
#include <dirent.h>
int
unlink(const char *pathname)
{
struct po_relpath rel_pathname = find_relative(pathname, __WASI_RIGHT_PATH_UNLINK_FILE, 0);
// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
if (rel_pathname.dirfd == -1) {
errno = ENOTCAPABLE;
return -1;
}
return __wasilibc_unlinkat(rel_pathname.dirfd, rel_pathname.relative_path);
}
int
rmdir(const char *pathname)
{

Loading…
Cancel
Save