Make redbean StoreAsset() work better

- Better UBSAN error messages
- POSIX Advisory Locks polyfills
- Move redbean manual to /.help.txt
- System call memory safety in ASAN mode
- Character classification now does UNICODE
This commit is contained in:
Justine Tunney 2021-05-14 05:36:58 -07:00
parent 919b6fec10
commit 690be544da
228 changed files with 3653 additions and 3015 deletions

View file

@ -137,8 +137,8 @@ int mlockall(int);
int munlock(const void *, size_t);
int munlockall(void);
int nice(int);
int open(const char *, int, ...) nodiscard;
int openanon(char *, unsigned) nodiscard;
int open(const char *, int, ...);
int openanon(char *, unsigned);
int openat(int, const char *, int, ...);
int pause(void);
int personality(uint64_t);
@ -176,7 +176,7 @@ int stat(const char *, struct stat *);
int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned);
int sysinfo(struct sysinfo *) paramsnonnull();
int sysinfo(struct sysinfo *);
int touch(const char *, uint32_t);
int truncate(const char *, uint64_t);
int ttyname_r(int, char *, size_t);

View file

@ -18,45 +18,98 @@
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/flock.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filelockflags.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/files.h"
#include "libc/nt/struct/byhandlefileinformation.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
textwindows int sys_fcntl_nt(int fd, int cmd, unsigned arg) {
static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) {
uint32_t flags;
struct flock *l;
struct NtOverlapped ov;
int64_t pos, off, len, size;
struct NtByHandleFileInformation info;
l = (struct flock *)arg;
len = l->l_len;
off = l->l_start;
if (!len || l->l_whence == SEEK_END) {
if (!GetFileInformationByHandle(f->handle, &info)) return __winerr();
size = (uint64_t)info.nFileSizeHigh << 32 | info.nFileSizeLow;
} else {
size = 0;
}
if (l->l_whence != SEEK_SET) {
if (l->l_whence == SEEK_CUR) {
if (!SetFilePointerEx(f->handle, 0, &pos, SEEK_CUR)) return __winerr();
off = pos + off;
} else if (l->l_whence == SEEK_END) {
off = size - off;
} else {
return einval();
}
}
if (!len) len = size - off;
if (off < 0 || len < 0) return einval();
offset2overlap(off, &ov);
if (l->l_type == F_RDLCK || l->l_type == F_WRLCK) {
flags = 0;
if (cmd == F_SETLK) flags |= kNtLockfileFailImmediately;
if (l->l_type == F_WRLCK) flags |= kNtLockfileExclusiveLock;
if (LockFileEx(f->handle, flags, 0, len, len >> 32, &ov)) {
return 0;
} else {
return __winerr();
}
} else if (l->l_type == F_UNLCK) {
if (UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
return 0;
} else {
return __winerr();
}
} else {
return einval();
}
}
textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
uint32_t flags;
if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) {
switch (cmd) {
case F_GETFL:
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
O_NOATIME | O_NONBLOCK);
case F_SETFL:
/*
* - O_APPEND doesn't appear to be tunable at cursory glance
* - O_NONBLOCK might require we start doing all i/o in threads
* - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
*/
return einval();
case F_GETFD:
if (g_fds.p[fd].flags & O_CLOEXEC) {
return FD_CLOEXEC;
} else {
return 0;
}
case F_SETFD:
if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC;
return FD_CLOEXEC;
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0;
}
default:
return einval();
if (cmd == F_GETFL) {
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
O_NOATIME | O_NONBLOCK);
} else if (cmd == F_SETFL) {
/*
* - O_APPEND doesn't appear to be tunable at cursory glance
* - O_NONBLOCK might require we start doing all i/o in threads
* - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
*/
return einval();
} else if (cmd == F_GETFD) {
if (g_fds.p[fd].flags & O_CLOEXEC) {
return FD_CLOEXEC;
} else {
return 0;
}
} else if (cmd == F_SETFD) {
if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC;
return FD_CLOEXEC;
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0;
}
} else if (cmd == F_SETLK || cmd == F_SETLKW) {
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
} else {
return einval();
}
} else {
return ebadf();

31
libc/calls/fcntl-sysv.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/struct/flock.h"
#include "libc/sysv/consts/f.h"
int sys_fcntl(int fd, int cmd, uintptr_t arg) {
int rc;
bool islock;
islock = cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK;
if (islock) cosmo2flock(arg);
rc = __sys_fcntl(fd, cmd, arg);
if (islock) flock2cosmo(arg);
return rc;
}

View file

@ -25,6 +25,12 @@
*
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
*
* This function implements POSIX Advisory Locks, e.g.
*
* CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK}));
* // ...
* CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK}));
*
* @param cmd can be F_{GET,SET}{FD,FL}, etc.
* @param arg can be FD_CLOEXEC, etc. depending
* @return 0 on success, or -1 w/ errno
@ -32,9 +38,9 @@
*/
int fcntl(int fd, int cmd, ...) {
va_list va;
unsigned arg;
uintptr_t arg;
va_start(va, cmd);
arg = va_arg(va, unsigned);
arg = va_arg(va, uintptr_t);
va_end(va);
if (!IsWindows()) {
return sys_fcntl(fd, cmd, arg);

View file

@ -28,7 +28,7 @@
int __fixupnewfd(int fd, int flags) {
if (fd != -1) {
if (flags & O_CLOEXEC) {
sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
__sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
}
}
return fd;

View file

@ -23,6 +23,8 @@
/**
* Acquires lock on file.
*
* Please note multiple file descriptors means multiple locks.
*
* @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive,
* non-blocking, and unlocking
* @return 0 on success, or -1 w/ errno

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
@ -28,6 +29,7 @@
* @asyncsignalsafe
*/
int fstat(int fd, struct stat *st) {
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
if (__isfdkind(fd, kFdZip)) {
return weaken(__zipos_fstat)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);

View file

@ -20,7 +20,9 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
@ -36,6 +38,7 @@
*/
int fstatat(int dirfd, const char *path, struct stat *st, uint32_t flags) {
struct ZiposUri zipname;
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
return weaken(__zipos_stat)(&zipname, st);
} else if (!IsWindows()) {

View file

@ -34,7 +34,7 @@ char *sys_getcwd_xnu(char *res, size_t size) {
if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) {
if (sys_fstat(fd, &st[0]) != -1) {
if (st[0].st_dev && st[0].st_ino) {
if (sys_fcntl(fd, XNU_F_GETPATH, buf) != -1) {
if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) {
if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) {
if (memccpy(res, buf, '\0', size)) {

View file

@ -22,7 +22,7 @@
* Returns parent process id.
* @asyncsignalsafe
*/
int32_t getppid(void) {
int getppid(void) {
if (!IsWindows()) {
if (!IsNetbsd()) {
return sys_getppid();

View file

@ -109,6 +109,7 @@ char *sys_getcwd(char *, u64) hidden;
char *sys_getcwd_xnu(char *, u64) hidden;
i32 __sys_dup3(i32, i32, i32) hidden;
i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
i32 __sys_fcntl(i32, i32, u64) hidden;
i32 __sys_fstat(i32, struct stat *) hidden;
i32 __sys_fstatat(i32, const char *, struct stat *, i32) hidden;
i32 __sys_getrusage(i32, struct rusage *) hidden;
@ -131,7 +132,7 @@ i32 sys_fchmod(i32, u32) hidden;
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
i32 sys_fchown(i64, u32, u32) hidden;
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
i32 sys_fcntl(i32, i32, ...) hidden;
i32 sys_fcntl(i32, i32, u64) hidden;
i32 sys_fdatasync(i32) hidden;
i32 sys_flock(i32, i32) hidden;
i32 sys_fstat(i32, struct stat *) hidden;
@ -229,6 +230,8 @@ int gethostname_nt(char *, size_t) hidden;
size_t __iovec_size(const struct iovec *, size_t) hidden;
void __rusage2linux(struct rusage *) hidden;
ssize_t WritevUninterruptible(int, struct iovec *, int);
void flock2cosmo(uintptr_t);
void cosmo2flock(uintptr_t);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § syscalls » windows nt » veneers
@ -245,7 +248,7 @@ int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
int sys_fadvise_nt(int, u64, u64, int) hidden;
int sys_fchdir_nt(int) hidden;
int sys_fcntl_nt(int, int, unsigned) hidden;
int sys_fcntl_nt(int, int, uintptr_t) hidden;
int sys_fdatasync_nt(int) hidden;
int sys_flock_nt(int, int) hidden;
int sys_fork_nt(void) hidden;

164
libc/calls/metaflock.c Normal file
View file

@ -0,0 +1,164 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/struct/flock.h"
union metaflock {
struct flock cosmo;
struct flock_linux {
int16_t l_type;
int16_t l_whence;
int64_t l_start;
int64_t l_len;
int32_t l_pid;
} linux;
struct flock_xnu {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} xnu;
struct flock_freebsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
} freebsd;
struct flock_openbsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} openbsd;
struct flock_netbsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} netbsd;
};
void flock2cosmo(uintptr_t memory) {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
union metaflock *u;
u = (union metaflock *)memory;
if (IsLinux()) {
l_start = u->linux.l_start;
l_len = u->linux.l_len;
l_pid = u->linux.l_pid;
l_type = u->linux.l_type;
l_whence = u->linux.l_whence;
l_sysid = 0;
} else if (IsXnu()) {
l_start = u->xnu.l_start;
l_len = u->xnu.l_len;
l_pid = u->xnu.l_pid;
l_type = u->xnu.l_type;
l_whence = u->xnu.l_whence;
l_sysid = 0;
} else if (IsFreebsd()) {
l_start = u->freebsd.l_start;
l_len = u->freebsd.l_len;
l_pid = u->freebsd.l_pid;
l_type = u->freebsd.l_type;
l_whence = u->freebsd.l_whence;
l_sysid = u->freebsd.l_sysid;
} else if (IsOpenbsd()) {
l_start = u->openbsd.l_start;
l_len = u->openbsd.l_len;
l_pid = u->openbsd.l_pid;
l_type = u->openbsd.l_type;
l_whence = u->openbsd.l_whence;
l_sysid = 0;
} else if (IsNetbsd()) {
l_start = u->netbsd.l_start;
l_len = u->netbsd.l_len;
l_pid = u->netbsd.l_pid;
l_type = u->netbsd.l_type;
l_whence = u->netbsd.l_whence;
l_sysid = 0;
} else {
return;
}
u->cosmo.l_start = l_start;
u->cosmo.l_len = l_len;
u->cosmo.l_pid = l_pid;
u->cosmo.l_type = l_type;
u->cosmo.l_whence = l_whence;
u->cosmo.l_sysid = l_sysid;
}
void cosmo2flock(uintptr_t memory) {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
union metaflock *u;
u = (union metaflock *)memory;
l_start = u->cosmo.l_start;
l_len = u->cosmo.l_len;
l_pid = u->cosmo.l_pid;
l_type = u->cosmo.l_type;
l_whence = u->cosmo.l_whence;
l_sysid = u->cosmo.l_sysid;
if (IsLinux()) {
u->linux.l_start = l_start;
u->linux.l_len = l_len;
u->linux.l_pid = l_pid;
u->linux.l_type = l_type;
u->linux.l_whence = l_whence;
} else if (IsXnu()) {
u->xnu.l_start = l_start;
u->xnu.l_len = l_len;
u->xnu.l_pid = l_pid;
u->xnu.l_type = l_type;
u->xnu.l_whence = l_whence;
} else if (IsFreebsd()) {
u->freebsd.l_start = l_start;
u->freebsd.l_len = l_len;
u->freebsd.l_pid = l_pid;
u->freebsd.l_type = l_type;
u->freebsd.l_whence = l_whence;
u->freebsd.l_sysid = l_sysid;
} else if (IsOpenbsd()) {
u->openbsd.l_start = l_start;
u->openbsd.l_len = l_len;
u->openbsd.l_pid = l_pid;
u->openbsd.l_type = l_type;
u->openbsd.l_whence = l_whence;
} else if (IsNetbsd()) {
u->netbsd.l_start = l_start;
u->netbsd.l_len = l_len;
u->netbsd.l_pid = l_pid;
u->netbsd.l_type = l_type;
u->netbsd.l_whence = l_whence;
}
}

View file

@ -36,7 +36,7 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
errno = err;
fd = __sys_openat(dirfd, file, flags & ~O_CLOEXEC, mode);
if (fd != -1 && (flags & O_CLOEXEC)) {
sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
__sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
}
}

View file

@ -23,6 +23,7 @@
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h"
#include "libc/sysv/consts/iov.h"
#include "libc/sysv/errfuns.h"
@ -45,6 +46,7 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
if (fd < 0) return einval();
if (iovlen < 0) return einval();
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);

View file

@ -22,6 +22,7 @@
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h"
#include "libc/sysv/consts/iov.h"
#include "libc/sysv/errfuns.h"
@ -49,6 +50,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
if (fd < 0) return einval();
if (iovlen < 0) return einval();
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
@ -31,18 +32,21 @@
* @asyncsignalsafe
*/
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
if (fd < 0) return einval();
if (iovlen < 0) return einval();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_readv(fd, iov, iovlen);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_readv_metal(g_fds.p + fd, iov, iovlen);
if (fd >= 0 && iovlen >= 0) {
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_readv(fd, iov, iovlen);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_readv_metal(g_fds.p + fd, iov, iovlen);
} else {
return sys_readv_nt(g_fds.p + fd, iov, iovlen);
}
} else {
return sys_readv_nt(g_fds.p + fd, iov, iovlen);
return einval();
}
}

View file

@ -2,12 +2,13 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct flock {
short l_type;
short l_whence;
int64_t l_start;
int64_t l_len;
int l_pid;
struct flock { /* cosmopolitan abi */
int16_t l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */
int16_t l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
int64_t l_start; /* starting offset */
int64_t l_len; /* 0 means until end of file */
int32_t l_pid; /* lock owner */
int32_t l_sysid; /* remote system id or zero for local */
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -21,11 +21,13 @@
#include "libc/calls/internal.h"
#include "libc/calls/struct/sysinfo.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/nt/accounting.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/memorystatusex.h"
#include "libc/nt/systeminfo.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
/**
* Returns amount of system ram, cores, etc.
@ -34,6 +36,11 @@
*/
int sysinfo(struct sysinfo *info) {
int rc;
if (IsAsan()) {
if (info && !__asan_is_valid(info, sizeof(*info))) {
return efault();
}
}
memset(info, 0, sizeof(*info));
if (!IsWindows()) {
rc = sys_sysinfo(info);

View file

@ -18,7 +18,9 @@
*/
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
/**
@ -30,6 +32,11 @@
* @see stat()
*/
int utimes(const char *path, const struct timeval tv[2]) {
if (IsAsan()) {
if (tv && !__asan_is_valid(tv, sizeof(*tv) * 2)) {
return efault();
}
}
if (!IsWindows()) {
/*
* we don't modernize utimes() into utimensat() because the

View file

@ -20,6 +20,8 @@
#include "libc/calls/internal.h"
#include "libc/calls/wait4.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h"
/**
* Waits for status to change on process.
@ -35,6 +37,16 @@
*/
int wait4(int pid, int *opt_out_wstatus, int options,
struct rusage *opt_out_rusage) {
if (IsAsan()) {
if (opt_out_wstatus &&
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) {
return efault();
}
if (opt_out_rusage &&
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))) {
return efault();
}
}
if (!IsWindows()) {
return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage);
} else {

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
@ -34,18 +35,21 @@
* @return number of bytes actually handed off, or -1 w/ errno
*/
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
if (fd < 0) return einval();
if (iovlen < 0) return einval();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_writev(fd, iov, iovlen);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
if (fd >= 0 && iovlen >= 0) {
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
} else if (!IsWindows() && !IsMetal()) {
return sys_writev(fd, iov, iovlen);
} else if (fd >= g_fds.n) {
return ebadf();
} else if (IsMetal()) {
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
} else {
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
}
} else {
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
return einval();
}
}