mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-05 02:38:31 +00:00
Fix bugs and regressions in the pledge command
This change gets the pledge (formerly pledge.com) command back in tip top shape for a 3.0.1 cosmos release. It now runs on all platforms, even though it's mostly a no-op on ones that lack the kernel security stuff. The binary footprint is now smaller, since it no longer needs to link malloc. It's also now able to be built as a fat binary.
This commit is contained in:
parent
b0e3d89942
commit
7b284f6bda
18 changed files with 493 additions and 272 deletions
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -37,13 +38,12 @@
|
|||
* @raise EBADF on OpenBSD if `first` is greater than highest fd
|
||||
* @raise EINVAL if flags are bad or first is greater than last
|
||||
* @raise EMFILE if a weird race condition happens on Linux
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise EINTR possibly on OpenBSD
|
||||
* @raise ENOMEM on Linux maybe
|
||||
*/
|
||||
int closefrom(int first) {
|
||||
int rc, err;
|
||||
(void)err;
|
||||
int rc;
|
||||
BLOCK_CANCELATION;
|
||||
if (first < 0) {
|
||||
// consistent with openbsd
|
||||
// freebsd allows this but it's dangerous
|
||||
|
@ -58,6 +58,7 @@ int closefrom(int first) {
|
|||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
ALLOW_CANCELATION;
|
||||
STRACE("closefrom(%d) → %d% m", first, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ ssize_t copyfd(int in, int out, size_t n) {
|
|||
if (dw != dr) {
|
||||
// POSIX requires atomic IO up to PIPE_BUF
|
||||
// The minimum permissible PIPE_BUF is 512
|
||||
abort();
|
||||
notpossible;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
|
|
|
@ -25,5 +25,6 @@
|
|||
bool IsApeLoadable(char buf[8]) {
|
||||
return READ32LE(buf) == READ32LE("\177ELF") ||
|
||||
READ64LE(buf) == READ64LE("MZqFpD='") ||
|
||||
READ64LE(buf) == READ64LE("JTqFpD='");
|
||||
READ64LE(buf) == READ64LE("jartsr='") ||
|
||||
READ64LE(buf) == READ64LE("APEDBG='");
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@ static int FindPromise(const char *name) {
|
|||
/**
|
||||
* Parses the arguments to pledge() into a bitmask.
|
||||
*
|
||||
* @param out receives the integral promises mask, which zero is defined
|
||||
* as the set of all promises, and -1 is defined as the empty set of
|
||||
* promises, which is equivalent to `promises` being an empty string
|
||||
* @return 0 on success, or -1 if invalid
|
||||
*/
|
||||
int ParsePromises(const char *promises, unsigned long *out,
|
||||
|
|
|
@ -535,7 +535,10 @@ static const struct thatispacked SyscallName {
|
|||
};
|
||||
|
||||
static const uint16_t kPledgeDefault[] = {
|
||||
__NR_linux_exit, // thread return / exit()
|
||||
__NR_linux_exit, // thread return / exit()
|
||||
#ifdef __NR_linux_arch_prctl //
|
||||
__NR_linux_arch_prctl, // or else launching musl process crashes (tls)
|
||||
#endif //
|
||||
};
|
||||
|
||||
// stdio contains all the benign system calls. openbsd makes the
|
||||
|
|
|
@ -29,6 +29,7 @@ void __stat2cosmo(struct stat *restrict st, const union metastat *ms) {
|
|||
st->st_uid = ms->linux.st_uid;
|
||||
st->st_gid = ms->linux.st_gid;
|
||||
st->st_flags = 0;
|
||||
st->st_gen = 0;
|
||||
st->st_rdev = ms->linux.st_rdev;
|
||||
st->st_size = ms->linux.st_size;
|
||||
st->st_blksize = ms->linux.st_blksize;
|
||||
|
|
|
@ -12,7 +12,7 @@ struct sysinfo {
|
|||
uint64_t bufferram; /* lingering disk pages; see fadvise */
|
||||
uint64_t totalswap; /* size of emergency memory */
|
||||
uint64_t freeswap; /* hopefully equal to totalswap */
|
||||
int16_t procs; /* number of processes */
|
||||
uint16_t procs; /* number of processes */
|
||||
int16_t __ignore1; /* padding */
|
||||
int32_t __ignore2; /* padding */
|
||||
uint64_t totalhigh; /* wut */
|
||||
|
|
|
@ -16,27 +16,55 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/struct/sysinfo.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/calls/struct/sysinfo.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/struct/memorystatusex.h"
|
||||
#include "libc/nt/struct/systeminfo.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
|
||||
static textwindows uint16_t GetProcessCount(void) {
|
||||
uint16_t res;
|
||||
uint32_t have, got, *pids;
|
||||
uint32_t stack_memory[1000];
|
||||
have = 0xFFFF * 4;
|
||||
if (!_weaken(malloc) || !(pids = _weaken(malloc)(have))) {
|
||||
pids = stack_memory;
|
||||
have = sizeof(stack_memory);
|
||||
}
|
||||
if (EnumProcesses(pids, have, &got)) {
|
||||
res = got / 4;
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
if (pids != stack_memory && _weaken(free)) {
|
||||
_weaken(free)(pids);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
textwindows int sys_sysinfo_nt(struct sysinfo *info) {
|
||||
int i;
|
||||
double load[3];
|
||||
struct NtMemoryStatusEx memstat;
|
||||
struct NtSystemInfo sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
BLOCK_SIGNALS;
|
||||
if (sys_getloadavg_nt(load, 3) != -1) {
|
||||
for (i = 0; i < 3; ++i) {
|
||||
info->loads[i] = load[i] * 65536;
|
||||
}
|
||||
}
|
||||
memstat.dwLength = sizeof(struct NtMemoryStatusEx);
|
||||
if (GlobalMemoryStatusEx(&memstat)) {
|
||||
info->mem_unit = 1;
|
||||
info->totalram = memstat.ullTotalPhys;
|
||||
info->freeram = memstat.ullAvailPhys;
|
||||
info->procs = sysinfo.dwNumberOfProcessors;
|
||||
info->uptime = GetTickCount64() / 1000;
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
info->uptime = GetTickCount64() / 1000;
|
||||
info->procs = GetProcessCount();
|
||||
info->mem_unit = 1;
|
||||
ALLOW_SIGNALS;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -188,56 +188,6 @@ static int unveil_init(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins paths, e.g.
|
||||
*
|
||||
* 0 + 0 → 0
|
||||
* "" + "" → ""
|
||||
* "a" + 0 → "a"
|
||||
* "a" + "" → "a/"
|
||||
* 0 + "b" → "b"
|
||||
* "" + "b" → "b"
|
||||
* "." + "b" → "./b"
|
||||
* "b" + "." → "b/."
|
||||
* "a" + "b" → "a/b"
|
||||
* "a/" + "b" → "a/b"
|
||||
* "a" + "b/" → "a/b/"
|
||||
* "a" + "/b" → "/b"
|
||||
*
|
||||
* @return joined path, which may be `buf`, `path`, or `other`, or null
|
||||
* if (1) `buf` didn't have enough space, or (2) both `path` and
|
||||
* `other` were null
|
||||
*/
|
||||
static char *JoinPaths(char *buf, size_t size, const char *path,
|
||||
const char *other) {
|
||||
size_t pathlen, otherlen;
|
||||
if (!other) return (char *)path;
|
||||
if (!path) return (char *)other;
|
||||
pathlen = strlen(path);
|
||||
if (!pathlen || *other == '/') {
|
||||
return (/*unconst*/ char *)other;
|
||||
}
|
||||
otherlen = strlen(other);
|
||||
if (path[pathlen - 1] == '/') {
|
||||
if (pathlen + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
memmove(buf + pathlen, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (pathlen + 1 + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
buf[pathlen] = '/';
|
||||
memmove(buf + pathlen + 1, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sys_unveil_linux(const char *path, const char *permissions) {
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wframe-larger-than="
|
||||
|
@ -302,7 +252,7 @@ int sys_unveil_linux(const char *path, const char *permissions) {
|
|||
// next = join(dirname(next), link)
|
||||
strcpy(b.buf2, next);
|
||||
dir = dirname(b.buf2);
|
||||
if ((next = JoinPaths(b.buf3, PATH_MAX, dir, b.lbuf))) {
|
||||
if ((next = __join_paths(b.buf3, PATH_MAX, dir, b.lbuf))) {
|
||||
// next now points to either: buf3, buf2, lbuf, rodata
|
||||
strcpy(b.buf4, next);
|
||||
next = b.buf4;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifdef __COSMOPOLITAN__
|
||||
#undef __COSMOPOLITAN__
|
||||
#endif
|
||||
|
||||
#define __COSMOPOLITAN_MAJOR__ 3
|
||||
#define __COSMOPOLITAN_MINOR__ 0
|
||||
#define __COSMOPOLITAN_PATCH__ 0
|
||||
|
|
|
@ -430,6 +430,9 @@ privileged void klog(const char *b, size_t n) {
|
|||
: "=a"(rax), "=D"(rdi), "=S"(rsi), "=d"(rdx)
|
||||
: "0"(__NR_write), "1"(h), "2"(b), "3"(n)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
if (rax < 0) {
|
||||
__klog_handle = 0;
|
||||
}
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
// this isn't a cancelation point because we don't acknowledge eintr
|
||||
|
@ -444,6 +447,9 @@ privileged void klog(const char *b, size_t n) {
|
|||
: "=r"(res_x0)
|
||||
: "r"(r0), "r"(r1), "r"(r2), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
if (res_x0 < 0) {
|
||||
__klog_handle = 0;
|
||||
}
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
|
|
69
libc/str/joinpaths.c
Normal file
69
libc/str/joinpaths.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-*- 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 2023 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/str/str.h"
|
||||
|
||||
/**
|
||||
* Joins paths, e.g.
|
||||
*
|
||||
* 0 + 0 → 0
|
||||
* "" + "" → ""
|
||||
* "a" + 0 → "a"
|
||||
* "a" + "" → "a/"
|
||||
* 0 + "b" → "b"
|
||||
* "" + "b" → "b"
|
||||
* "." + "b" → "./b"
|
||||
* "b" + "." → "b/."
|
||||
* "a" + "b" → "a/b"
|
||||
* "a/" + "b" → "a/b"
|
||||
* "a" + "b/" → "a/b/"
|
||||
* "a" + "/b" → "/b"
|
||||
*
|
||||
* @return joined path, which may be `buf`, `path`, or `other`, or null
|
||||
* if (1) `buf` didn't have enough space, or (2) both `path` and
|
||||
* `other` were null
|
||||
*/
|
||||
char *__join_paths(char *buf, size_t size, const char *path,
|
||||
const char *other) {
|
||||
size_t pathlen, otherlen;
|
||||
if (!other) return (char *)path;
|
||||
if (!path) return (char *)other;
|
||||
pathlen = strlen(path);
|
||||
if (!pathlen || *other == '/') {
|
||||
return (/*unconst*/ char *)other;
|
||||
}
|
||||
otherlen = strlen(other);
|
||||
if (path[pathlen - 1] == '/') {
|
||||
if (pathlen + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
memmove(buf + pathlen, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (pathlen + 1 + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
buf[pathlen] = '/';
|
||||
memmove(buf + pathlen + 1, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -217,6 +217,7 @@ axdx_t tprecode8to16(char16_t *, size_t, const char *);
|
|||
axdx_t tprecode16to8(char *, size_t, const char16_t *);
|
||||
bool wcsstartswith(const wchar_t *, const wchar_t *) strlenesque;
|
||||
bool wcsendswith(const wchar_t *, const wchar_t *) strlenesque;
|
||||
char *__join_paths(char *, size_t, const char *, const char *) __wur;
|
||||
#endif /* _COSMO_SOURCE */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue