From 817cf6a82efa7ed274371a28621bbf88a723d9b7 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Tue, 6 Dec 2022 23:48:35 +0100 Subject: [PATCH] Update wasi-libc to 8b7148f69ae241a2749b3defe4606da8143b72e0 (#13793) --- .../cloudlibc/src/libc/dirent/readdir.c | 31 ++++++++++++++++++- .../musl/src/env/__stack_chk_fail.c | 18 +++++++++++ src/target.zig | 4 +-- src/wasi_libc.zig | 1 + 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/libc/wasi/libc-bottom-half/cloudlibc/src/libc/dirent/readdir.c b/lib/libc/wasi/libc-bottom-half/cloudlibc/src/libc/dirent/readdir.c index b5650d6cdf..bfd19213c6 100644 --- a/lib/libc/wasi/libc-bottom-half/cloudlibc/src/libc/dirent/readdir.c +++ b/lib/libc/wasi/libc-bottom-half/cloudlibc/src/libc/dirent/readdir.c @@ -3,6 +3,9 @@ // SPDX-License-Identifier: BSD-2-Clause #include +#include +#include +#include #include #include @@ -77,10 +80,36 @@ struct dirent *readdir(DIR *dirp) { GROW(dirp->dirent, dirp->dirent_size, offsetof(struct dirent, d_name) + entry.d_namlen + 1); struct dirent *dirent = dirp->dirent; - dirent->d_ino = entry.d_ino; dirent->d_type = entry.d_type; memcpy(dirent->d_name, name, entry.d_namlen); dirent->d_name[entry.d_namlen] = '\0'; + + // `fd_readdir` implementations may set the inode field to zero if the + // the inode number is unknown. In that case, do an `fstatat` to get the + // inode number. + off_t d_ino = entry.d_ino; + unsigned char d_type = entry.d_type; + if (d_ino == 0 && strcmp(dirent->d_name, "..") != 0) { + struct stat statbuf; + if (fstatat(dirp->fd, dirent->d_name, &statbuf, AT_SYMLINK_NOFOLLOW) != 0) { + if (errno == ENOENT) { + // The file disappeared before we could read it, so skip it. + dirp->buffer_processed += entry_size; + continue; + } + return NULL; + } + + // Fill in the inode. + d_ino = statbuf.st_ino; + + // In case someone raced with us and replaced the object with this name + // with another of a different type, update the type too. + d_type = __wasilibc_iftodt(statbuf.st_mode & S_IFMT); + } + dirent->d_ino = d_ino; + dirent->d_type = d_type; + dirp->cookie = entry.d_next; dirp->buffer_processed += entry_size; return dirent; diff --git a/lib/libc/wasi/libc-top-half/musl/src/env/__stack_chk_fail.c b/lib/libc/wasi/libc-top-half/musl/src/env/__stack_chk_fail.c index e53526020f..cb7a3f3911 100644 --- a/lib/libc/wasi/libc-top-half/musl/src/env/__stack_chk_fail.c +++ b/lib/libc/wasi/libc-top-half/musl/src/env/__stack_chk_fail.c @@ -1,6 +1,11 @@ #include #include +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) #include "pthread_impl.h" +#else +// In non-_REENTRANT, include it for `a_crash` +# include "atomic.h" +#endif uintptr_t __stack_chk_guard; @@ -18,7 +23,9 @@ void __init_ssp(void *entropy) ((char *)&__stack_chk_guard)[1] = 0; #endif +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) __pthread_self()->canary = __stack_chk_guard; +#endif } void __stack_chk_fail(void) @@ -29,3 +36,14 @@ void __stack_chk_fail(void) hidden void __stack_chk_fail_local(void); weak_alias(__stack_chk_fail, __stack_chk_fail_local); + +#ifndef __wasilibc_unmodified_upstream +# include + +__attribute__((constructor(60))) +static void __wasilibc_init_ssp(void) { + uintptr_t entropy; + int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t)); + __init_ssp(r ? NULL : &entropy); +} +#endif diff --git a/src/target.zig b/src/target.zig index debcfb3776..f118a47724 100644 --- a/src/target.zig +++ b/src/target.zig @@ -328,8 +328,8 @@ pub fn supportsStackProbing(target: std.Target) bool { } pub fn supportsStackProtector(target: std.Target) bool { - // TODO: investigate whether stack-protector works on wasm - return !target.isWasm(); + _ = target; + return true; } pub fn libcProvidesStackProtector(target: std.Target) bool { diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index 7a52ea030e..fc8c81d5af 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -551,6 +551,7 @@ const libc_top_half_src_files = [_][]const u8{ "wasi/libc-top-half/musl/src/fcntl/creat.c", "wasi/libc-top-half/musl/src/dirent/alphasort.c", "wasi/libc-top-half/musl/src/dirent/versionsort.c", + "wasi/libc-top-half/musl/src/env/__stack_chk_fail.c", "wasi/libc-top-half/musl/src/env/clearenv.c", "wasi/libc-top-half/musl/src/env/getenv.c", "wasi/libc-top-half/musl/src/env/putenv.c",