mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-26 04:20:30 +00:00
Rewrite Linux pledge() code so it can be a payload
It's now possible to build our pledge() polyfill as a dynamic shared object that can be injected into a glibc executable using LD_PRELOAD
This commit is contained in:
parent
7bd4179b9b
commit
0277d7d6e9
37 changed files with 1980 additions and 1600 deletions
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -39,11 +40,18 @@ privileged wontreturn void _Exit(int exitcode) {
|
|||
int i;
|
||||
STRACE("_Exit(%d)", exitcode);
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit_group), "D"(exitcode)
|
||||
: "rcx", "r11", "memory");
|
||||
// this should only be possible on Linux in a pledge ultra sandbox
|
||||
// On Linux _Exit1 (exit) must be called in pledge("") mode. If we
|
||||
// call _Exit (exit_group) when we haven't used pledge("stdio") then
|
||||
// it'll terminate the process instead. On OpenBSD we must not call
|
||||
// _Exit1 (__threxit) because only _Exit (exit) is whitelisted when
|
||||
// operating in pledge("") mode.
|
||||
if (!(IsLinux() && !PLEDGED(STDIO))) {
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit_group), "D"(exitcode)
|
||||
: "rcx", "r11", "memory");
|
||||
}
|
||||
// Inline _Exit1() just in case _Exit() isn't allowed by pledge()
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit), "D"(exitcode)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
@ -35,6 +36,12 @@ privileged wontreturn void _Exit1(int rc) {
|
|||
struct WinThread *wt;
|
||||
STRACE("_Exit1(%d)", rc);
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
if (IsOpenbsd() && !PLEDGED(STDIO)) {
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit), "D"(rc)
|
||||
: "rcx", "r11", "memory");
|
||||
}
|
||||
asm volatile("xor\t%%r10d,%%r10d\n\t"
|
||||
"syscall"
|
||||
: /* no outputs */
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/pledge.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
|
||||
// XXX: should be inherited thread local
|
||||
unsigned __pledge_mode;
|
||||
// see also sys_pledge_linux() which is 100% pure
|
||||
enum PledgeMode __pledge_mode;
|
||||
unsigned long __promises;
|
||||
unsigned long __execpromises;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define PROMISE_PROT_EXEC 18
|
||||
#define PROMISE_VMINFO 19
|
||||
#define PROMISE_TMPPATH 20
|
||||
#define PROMISE_LEN_ 21
|
||||
|
||||
#define PLEDGED(x) ((~__promises >> PROMISE_##x) & 1)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue