Skip to content

Instantly share code, notes, and snippets.

@thejh
Created March 11, 2015 19:55
Show Gist options
  • Save thejh/45c800ef484a3d406120 to your computer and use it in GitHub Desktop.
Save thejh/45c800ef484a3d406120 to your computer and use it in GitHub Desktop.
PoC for blocking signals under SECCOMP_MODE_STRICT
#define _GNU_SOURCE
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <stdint.h>
#include <stddef.h>
#define __u16 uint16_t
#define __u32 uint32_t
#define __u64 uint64_t
struct sigcontext {
__u64 r8;
__u64 r9;
__u64 r10;
__u64 r11;
__u64 r12;
__u64 r13;
__u64 r14;
__u64 r15;
__u64 rdi;
__u64 rsi;
__u64 rbp;
__u64 rbx;
__u64 rdx;
__u64 rax;
__u64 rcx;
__u64 rsp;
__u64 rip;
__u64 eflags; /* RFLAGS */
__u16 cs;
__u16 gs;
__u16 fs;
__u16 __pad0;
__u64 err;
__u64 trapno;
__u64 oldmask;
__u64 cr2;
void *fpstate; /* zero when no FPU context */
//__u32 __fpstate_pad; /* has to be uncommented if X32 is enabled? */
__u64 reserved1[8];
};
typedef struct sigaltstack {
void *ss_sp;
int ss_flags;
size_t ss_size;
} stack_t;
#define _NSIG 64
#define _NSIG_BPW 64
#define _NSIG_WORDS (_NSIG / _NSIG_BPW) /* 1 */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
};
struct rt_sigframe {
/* char *pretcode; */
struct ucontext uc;
/* siginfo and fp state follow here */
};
void after_syscall(void) {
while (1) /* waste CPU time */;
}
#define GDT_ENTRY_DEFAULT_USER_DS 5
#define GDT_ENTRY_DEFAULT_USER_CS 6
void do_syscall(void) {
struct rt_sigframe sfr = { 0 };
sfr.uc.uc_stack.ss_flags = 0xf; /* invalid */
sfr.uc.uc_mcontext.rsp = (__u64)&sfr;
sfr.uc.uc_mcontext.rip = (__u64)after_syscall;
sfr.uc.uc_mcontext.cs = (GDT_ENTRY_DEFAULT_USER_CS << 3) | 3;
sfr.uc.uc_mcontext.gs = (GDT_ENTRY_DEFAULT_USER_DS << 3) | 3;
sfr.uc.uc_mcontext.fs = (GDT_ENTRY_DEFAULT_USER_DS << 3) | 3;
sfr.uc.uc_sigmask.sig[0] = 0xffffffffffffffffUL;
asm volatile ("mov %0, %%rsp\n\t"
"mov $15, %%rax\n\t" /* rt_sigreturn */
"syscall"
:: "r"(&sfr) :);
}
int main(void) {
int r = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
if (r) return 1;
asm("sub $0x10000, %rsp\n\t"
"call do_syscall");
return 50;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment