mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-26 07:49:05 +00:00
Explicitly disable Linux capabilities
This commit is contained in:
parent
ffedbfe14d
commit
16fc83f9ce
12 changed files with 269 additions and 20 deletions
|
@ -31,25 +31,36 @@
|
|||
privileged int prctl(int operation, ...) {
|
||||
int rc;
|
||||
va_list va;
|
||||
intptr_t a, b;
|
||||
register intptr_t c asm("r10");
|
||||
register intptr_t d asm("r8");
|
||||
intptr_t a, b, c, d;
|
||||
|
||||
va_start(va, operation);
|
||||
a = va_arg(va, intptr_t);
|
||||
b = va_arg(va, intptr_t);
|
||||
c = va_arg(va, intptr_t);
|
||||
d = va_arg(va, intptr_t);
|
||||
va_end(va);
|
||||
|
||||
if (IsLinux()) {
|
||||
asm volatile("syscall"
|
||||
asm volatile("mov\t%5,%%r10\n\t"
|
||||
"mov\t%6,%%r8\n\t"
|
||||
"syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(157), "D"(operation), "S"(a), "d"(b), "r"(c), "r"(d)
|
||||
: "rcx", "r11", "memory");
|
||||
: "0"(157), "D"(operation), "S"(a), "d"(b), "g"(c), "g"(d)
|
||||
: "rcx", "r8", "r10", "r11", "memory");
|
||||
if (rc > -4096u) errno = -rc, rc = -1;
|
||||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
STRACE("prctl(%s, %p, %p, %p, %p) → %d% m", DescribePrctlOperation(operation),
|
||||
a, b, c, d, rc);
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
if (operation == PR_CAPBSET_READ || operation == PR_CAPBSET_DROP) {
|
||||
STRACE("prctl(%s, %s) → %d% m", DescribePrctlOperation(operation),
|
||||
DescribeCapability(a), rc);
|
||||
} else {
|
||||
STRACE("prctl(%s, %p, %p, %p, %p) → %d% m",
|
||||
DescribePrctlOperation(operation), a, b, c, d, rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
82
libc/intrin/describecapability.c
Normal file
82
libc/intrin/describecapability.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*-*- 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 2022 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/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/cap.h"
|
||||
|
||||
static const struct thatispacked {
|
||||
unsigned char x;
|
||||
const char *s;
|
||||
} kCapabilityName[] = {
|
||||
{CAP_CHOWN, "CHOWN"}, //
|
||||
{CAP_DAC_OVERRIDE, "DAC_OVERRIDE"}, //
|
||||
{CAP_DAC_READ_SEARCH, "DAC_READ_SEARCH"}, //
|
||||
{CAP_FOWNER, "FOWNER"}, //
|
||||
{CAP_FSETID, "FSETID"}, //
|
||||
{CAP_KILL, "KILL"}, //
|
||||
{CAP_SETGID, "SETGID"}, //
|
||||
{CAP_SETUID, "SETUID"}, //
|
||||
{CAP_SETPCAP, "SETPCAP"}, //
|
||||
{CAP_LINUX_IMMUTABLE, "LINUX_IMMUTABLE"}, //
|
||||
{CAP_NET_BIND_SERVICE, "NET_BIND_SERVICE"}, //
|
||||
{CAP_NET_BROADCAST, "NET_BROADCAST"}, //
|
||||
{CAP_NET_ADMIN, "NET_ADMIN"}, //
|
||||
{CAP_NET_RAW, "NET_RAW"}, //
|
||||
{CAP_IPC_LOCK, "IPC_LOCK"}, //
|
||||
{CAP_IPC_OWNER, "IPC_OWNER"}, //
|
||||
{CAP_SYS_MODULE, "SYS_MODULE"}, //
|
||||
{CAP_SYS_RAWIO, "SYS_RAWIO"}, //
|
||||
{CAP_SYS_CHROOT, "SYS_CHROOT"}, //
|
||||
{CAP_SYS_PTRACE, "SYS_PTRACE"}, //
|
||||
{CAP_SYS_PACCT, "SYS_PACCT"}, //
|
||||
{CAP_SYS_ADMIN, "SYS_ADMIN"}, //
|
||||
{CAP_SYS_BOOT, "SYS_BOOT"}, //
|
||||
{CAP_SYS_NICE, "SYS_NICE"}, //
|
||||
{CAP_SYS_RESOURCE, "SYS_RESOURCE"}, //
|
||||
{CAP_SYS_TIME, "SYS_TIME"}, //
|
||||
{CAP_SYS_TTY_CONFIG, "SYS_TTY_CONFIG"}, //
|
||||
{CAP_MKNOD, "MKNOD"}, //
|
||||
{CAP_LEASE, "LEASE"}, //
|
||||
{CAP_AUDIT_WRITE, "AUDIT_WRITE"}, //
|
||||
{CAP_AUDIT_CONTROL, "AUDIT_CONTROL"}, //
|
||||
{CAP_SETFCAP, "SETFCAP"}, //
|
||||
{CAP_MAC_OVERRIDE, "MAC_OVERRIDE"}, //
|
||||
{CAP_MAC_ADMIN, "MAC_ADMIN"}, //
|
||||
{CAP_SYSLOG, "SYSLOG"}, //
|
||||
{CAP_WAKE_ALARM, "WAKE_ALARM"}, //
|
||||
{CAP_BLOCK_SUSPEND, "BLOCK_SUSPEND"}, //
|
||||
{CAP_AUDIT_READ, "AUDIT_READ"}, //
|
||||
{CAP_PERFMON, "PERFMON"}, //
|
||||
{CAP_BPF, "BPF"}, //
|
||||
{CAP_CHECKPOINT_RESTORE, "CHECKPOINT_RESTORE"}, //
|
||||
};
|
||||
|
||||
const char *(DescribeCapability)(char buf[20], int x) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(kCapabilityName); ++i) {
|
||||
if (kCapabilityName[i].x == x) {
|
||||
stpcpy(stpcpy(buf, "CAP_"), kCapabilityName[i].s);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
}
|
|
@ -24,6 +24,7 @@ struct thatispacked DescribeFlags {
|
|||
const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t,
|
||||
const char *, unsigned);
|
||||
|
||||
const char *DescribeCapability(char[20], int);
|
||||
const char *DescribeClockName(char[32], int);
|
||||
const char *DescribeDirfd(char[12], int);
|
||||
const char *DescribeFrame(char[32], int);
|
||||
|
@ -74,6 +75,7 @@ const char *DescribeTimeval(char[45], int, const struct timeval *);
|
|||
void DescribeIov(const struct iovec *, int, ssize_t);
|
||||
void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
||||
|
||||
#define DescribeCapability(x) DescribeCapability(alloca(20), x)
|
||||
#define DescribeClockName(x) DescribeClockName(alloca(32), x)
|
||||
#define DescribeDirfd(dirfd) DescribeDirfd(alloca(12), dirfd)
|
||||
#define DescribeFrame(x) DescribeFrame(alloca(32), x)
|
||||
|
|
|
@ -27,6 +27,10 @@ const char *DescribePrctlOperation(int x) {
|
|||
return "PR_SET_SECCOMP";
|
||||
case PR_GET_SECCOMP:
|
||||
return "PR_GET_SECCOMP";
|
||||
case PR_CAPBSET_READ:
|
||||
return "PR_CAPBSET_READ";
|
||||
case PR_CAPBSET_DROP:
|
||||
return "PR_CAPBSET_DROP";
|
||||
default:
|
||||
return "PRCTL_???";
|
||||
}
|
||||
|
|
|
@ -1045,16 +1045,18 @@ static bool AllowSocketUnix(struct Filter *f) {
|
|||
// - PR_GET_SECCOMP (21)
|
||||
// - PR_SET_SECCOMP (22)
|
||||
// - PR_SET_NO_NEW_PRIVS (38)
|
||||
// - PR_CAPBSET_READ (23)
|
||||
//
|
||||
static bool AllowPrctl(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prctl, 0, 9 - 1),
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prctl, 0, 10 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 15, 7 - 3, 0),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 16, 7 - 4, 0),
|
||||
/*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 21, 7 - 5, 0),
|
||||
/*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 7 - 6, 0),
|
||||
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 38, 0, 8 - 7),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 15, 5, 0),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 16, 4, 0),
|
||||
/*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 21, 3, 0),
|
||||
/*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 2, 0),
|
||||
/*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 23, 1, 0),
|
||||
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 38, 0, 1),
|
||||
/*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L9*/ /* next filter */
|
||||
|
|
|
@ -48,8 +48,10 @@
|
|||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/cap.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
@ -137,6 +139,9 @@ static noasan void PrintDependencies(const char *prologue) {
|
|||
} while ((ldr = ldr->Next) && ldr != head);
|
||||
}
|
||||
|
||||
static noasan void Print(const char *prologue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints lots of information about this process, e.g.
|
||||
*
|
||||
|
@ -150,6 +155,7 @@ textstartup void __printargs(const char *prologue) {
|
|||
long key;
|
||||
char **env;
|
||||
sigset_t ss;
|
||||
bool gotsome;
|
||||
unsigned i, n;
|
||||
int e, x, flags;
|
||||
uintptr_t *auxp;
|
||||
|
@ -223,8 +229,9 @@ textstartup void __printargs(const char *prologue) {
|
|||
PRINT(" L%d%s%s %u-way %,u byte cache w/%s "
|
||||
"%,u sets of %,u byte lines shared across %u threads%s",
|
||||
CPUID4_CACHE_LEVEL,
|
||||
CPUID4_CACHE_TYPE == 1 ? " data"
|
||||
: CPUID4_CACHE_TYPE == 2 ? " code" : "",
|
||||
CPUID4_CACHE_TYPE == 1 ? " data"
|
||||
: CPUID4_CACHE_TYPE == 2 ? " code"
|
||||
: "",
|
||||
CPUID4_IS_FULLY_ASSOCIATIVE ? " fully-associative" : "",
|
||||
CPUID4_WAYS_OF_ASSOCIATIVITY, CPUID4_CACHE_SIZE_IN_BYTES,
|
||||
CPUID4_PHYSICAL_LINE_PARTITIONS > 1 ? " physically partitioned" : "",
|
||||
|
@ -289,6 +296,24 @@ textstartup void __printargs(const char *prologue) {
|
|||
PRINT(" error: sigprocmask() failed %m");
|
||||
}
|
||||
|
||||
if (IsLinux()) {
|
||||
PRINT("");
|
||||
PRINT("CAPABILITIES");
|
||||
if (prctl(PR_CAPBSET_READ, 0) != -1) {
|
||||
for (gotsome = i = 0; i <= CAP_LAST_CAP; ++i) {
|
||||
if (prctl(PR_CAPBSET_READ, i) == 1) {
|
||||
PRINT(" ☼ %s", DescribeCapability(i));
|
||||
gotsome = true;
|
||||
}
|
||||
}
|
||||
if (!gotsome) {
|
||||
PRINT(" ☼ %s", "none");
|
||||
}
|
||||
} else {
|
||||
PRINT(" ☼ %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
PRINT("RESOURCE LIMITS");
|
||||
for (i = 0; i < RLIM_NLIMITS; ++i) {
|
||||
|
|
47
libc/sysv/consts/cap.h
Normal file
47
libc/sysv/consts/cap.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CAP_H_
|
||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_CAP_H_
|
||||
|
||||
#define CAP_CHOWN 0
|
||||
#define CAP_DAC_OVERRIDE 1
|
||||
#define CAP_DAC_READ_SEARCH 2
|
||||
#define CAP_FOWNER 3
|
||||
#define CAP_FSETID 4
|
||||
#define CAP_KILL 5
|
||||
#define CAP_SETGID 6
|
||||
#define CAP_SETUID 7
|
||||
#define CAP_SETPCAP 8
|
||||
#define CAP_LINUX_IMMUTABLE 9
|
||||
#define CAP_NET_BIND_SERVICE 10
|
||||
#define CAP_NET_BROADCAST 11
|
||||
#define CAP_NET_ADMIN 12
|
||||
#define CAP_NET_RAW 13
|
||||
#define CAP_IPC_LOCK 14
|
||||
#define CAP_IPC_OWNER 15
|
||||
#define CAP_SYS_MODULE 16
|
||||
#define CAP_SYS_RAWIO 17
|
||||
#define CAP_SYS_CHROOT 18
|
||||
#define CAP_SYS_PTRACE 19
|
||||
#define CAP_SYS_PACCT 20
|
||||
#define CAP_SYS_ADMIN 21
|
||||
#define CAP_SYS_BOOT 22
|
||||
#define CAP_SYS_NICE 23
|
||||
#define CAP_SYS_RESOURCE 24
|
||||
#define CAP_SYS_TIME 25
|
||||
#define CAP_SYS_TTY_CONFIG 26
|
||||
#define CAP_MKNOD 27
|
||||
#define CAP_LEASE 28
|
||||
#define CAP_AUDIT_WRITE 29
|
||||
#define CAP_AUDIT_CONTROL 30
|
||||
#define CAP_SETFCAP 31
|
||||
#define CAP_MAC_OVERRIDE 32
|
||||
#define CAP_MAC_ADMIN 33
|
||||
#define CAP_SYSLOG 34
|
||||
#define CAP_WAKE_ALARM 35
|
||||
#define CAP_BLOCK_SUSPEND 36
|
||||
#define CAP_AUDIT_READ 37
|
||||
#define CAP_PERFMON 38
|
||||
#define CAP_BPF 39
|
||||
#define CAP_CHECKPOINT_RESTORE 40
|
||||
#define CAP_LAST_CAP CAP_CHECKPOINT_RESTORE
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CAP_H_ */
|
38
libc/sysv/consts/fs.h
Normal file
38
libc/sysv/consts/fs.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FS_H_
|
||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FS_H_
|
||||
|
||||
#define FS_IOC_GETFLAGS 0x80086601
|
||||
#define FS_IOC_SETFLAGS 0x40086602
|
||||
#define FS_IOC_GETVERSION 0x80087601
|
||||
#define FS_IOC_SETVERSION 0x40087602
|
||||
#define FS_IOC_FIEMAP 0xc020660b
|
||||
#define FS_IOC_FSGETXATTR 0x801c581f
|
||||
#define FS_IOC_FSSETXATTR 0x401c5820
|
||||
#define FS_IOC_GETFSLABEL 0x81009431
|
||||
#define FS_IOC_SETFSLABEL 0x41009432
|
||||
|
||||
#define FS_FL_USER_VISIBLE 0x0003DFFF /* user visible flags */
|
||||
#define FS_FL_USER_MODIFIABLE 0x000380FF /* user modifiable flags */
|
||||
#define FS_SECRM_FL 0x00000001 /* secure deletion */
|
||||
#define FS_UNRM_FL 0x00000002 /* undelete */
|
||||
#define FS_COMPR_FL 0x00000004 /* compress */
|
||||
#define FS_SYNC_FL 0x00000008 /* synchronous */
|
||||
#define FS_IMMUTABLE_FL 0x00000010
|
||||
#define FS_APPEND_FL 0x00000020 /* append-only */
|
||||
#define FS_NODUMP_FL 0x00000040
|
||||
#define FS_NOATIME_FL 0x00000080
|
||||
#define FS_DIRTY_FL 0x00000100
|
||||
#define FS_COMPRBLK_FL 0x00000200
|
||||
#define FS_NOCOMP_FL 0x00000400
|
||||
#define FS_ENCRYPT_FL 0x00000800 /* encrypted file */
|
||||
#define FS_BTREE_FL 0x00001000
|
||||
#define FS_INDEX_FL 0x00001000 /* hash-indexed directory */
|
||||
#define FS_IMAGIC_FL 0x00002000
|
||||
#define FS_JOURNAL_DATA_FL 0x00004000
|
||||
#define FS_NOTAIL_FL 0x00008000
|
||||
#define FS_DIRSYNC_FL 0x00010000
|
||||
#define FS_TOPDIR_FL 0x00020000
|
||||
#define FS_HUGE_FILE_FL 0x00040000
|
||||
#define FS_EXTENT_FL 0x00080000
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FS_H_ */
|
|
@ -7,6 +7,9 @@
|
|||
#define SECCOMP_MODE_STRICT 1
|
||||
#define SECCOMP_MODE_FILTER 2
|
||||
|
||||
#define PR_CAPBSET_READ 23
|
||||
#define PR_CAPBSET_DROP 24
|
||||
|
||||
#define PR_SET_NO_NEW_PRIVS 38
|
||||
#define PR_GET_NO_NEW_PRIVS 39
|
||||
|
||||
|
@ -73,8 +76,6 @@
|
|||
#define PR_SET_MM_EXE_FILE 13
|
||||
#define PR_SET_MM_MAP 14
|
||||
#define PR_SET_MM_MAP_SIZE 15
|
||||
#define PR_CAPBSET_READ 23
|
||||
#define PR_CAPBSET_DROP 24
|
||||
#define PR_GET_TSC 25
|
||||
#define PR_SET_TSC 26
|
||||
#define PR_GET_SECUREBITS 27
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
#include "libc/sysv/consts/prio.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
|
@ -66,6 +67,7 @@ usage: pledge.com [-hnN] PROG ARGS...\n\
|
|||
-c PATH call chroot()\n\
|
||||
-v [PERM:]PATH call unveil(PATH, PERM[rwxc])\n\
|
||||
-n set maximum niceness\n\
|
||||
-D don't drop capabilities\n\
|
||||
-N don't normalize file descriptors\n\
|
||||
-C SECS set cpu limit [default: inherited]\n\
|
||||
-M BYTES set virtual memory limit [default: 4gb]\n\
|
||||
|
@ -116,6 +118,7 @@ long g_cpuquota;
|
|||
long g_fszquota;
|
||||
long g_memquota;
|
||||
long g_proquota;
|
||||
long g_dontdrop;
|
||||
const char *g_chroot;
|
||||
const char *g_promises;
|
||||
|
||||
|
@ -133,7 +136,7 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
g_fszquota = 4 * 1000 * 1000 * 1000;
|
||||
g_memquota = 4L * 1024 * 1024 * 1024;
|
||||
if (!sysinfo(&si)) g_memquota = si.totalram;
|
||||
while ((opt = getopt(argc, argv, "hnNp:u:g:c:C:P:M:F:v:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "hnNp:u:g:c:C:D:P:M:F:v:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
g_nice = true;
|
||||
|
@ -141,6 +144,9 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
case 'N':
|
||||
g_noclose = true;
|
||||
break;
|
||||
case 'D':
|
||||
g_dontdrop = true;
|
||||
break;
|
||||
case 'c':
|
||||
g_chroot = optarg;
|
||||
break;
|
||||
|
@ -493,6 +499,21 @@ void ApplyFilesystemPolicy(unsigned long ipromises) {
|
|||
}
|
||||
}
|
||||
|
||||
void DropCapabilities(void) {
|
||||
int e, i;
|
||||
for (e = errno, i = 0;; ++i) {
|
||||
if (prctl(PR_CAPBSET_DROP, i) == -1) {
|
||||
if (errno == EINVAL || errno == EPERM) {
|
||||
errno = e;
|
||||
break;
|
||||
} else {
|
||||
kprintf("error: prctl(PR_CAPBSET_DROP, %d) failed: %m\n", i);
|
||||
_Exit(25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
bool hasfunbits;
|
||||
int useruid, usergid;
|
||||
|
@ -531,6 +552,15 @@ int main(int argc, char *argv[]) {
|
|||
owneruid = geteuid();
|
||||
hasfunbits = usergid != ownergid || useruid != owneruid;
|
||||
|
||||
if (g_dontdrop) {
|
||||
if (hasfunbits) {
|
||||
kprintf("error: -D flag forbidden on setuid binaries\n");
|
||||
_Exit(6);
|
||||
}
|
||||
} else {
|
||||
DropCapabilities();
|
||||
}
|
||||
|
||||
if (hasfunbits) {
|
||||
setuid(owneruid);
|
||||
setgid(ownergid);
|
||||
|
|
|
@ -735,7 +735,7 @@ FUNCTIONS
|
|||
|
||||
Turns Lua data structure into JSON string.
|
||||
|
||||
Since Lua uses tables for both hashmaps and arrays, we use a
|
||||
Since Lua uses tables are both hashmaps and arrays, we use a
|
||||
simple fast algorithm for telling the two apart. Tables with
|
||||
non-zero length (as reported by `#`) are encoded as arrays,
|
||||
and any non-array elements are ignored. For example:
|
||||
|
|
|
@ -7295,6 +7295,13 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
|
||||
void RedBean(int argc, char *argv[]) {
|
||||
if (IsLinux()) {
|
||||
// disable weird linux capabilities
|
||||
for (int e = errno, i = 0;; ++i) {
|
||||
if (prctl(PR_CAPBSET_DROP, i) == -1) {
|
||||
errno = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// disable sneak privilege since we don't use them
|
||||
// seccomp will fail later if this fails
|
||||
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue