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`,
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:
*/
#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)
{