123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- diff --git a/Kconfig b/Kconfig
- index c13f48d..e18713e 100644
- --- a/Kconfig
- +++ b/Kconfig
- @@ -9,3 +9,4 @@ config SRCARCH
- option env="SRCARCH"
-
- source "arch/$SRCARCH/Kconfig"
- +source "graphene/Kconfig"
- diff --git a/Makefile b/Makefile
- index e5ac8a6..116ac82 100644
- --- a/Makefile
- +++ b/Makefile
- @@ -779,7 +779,7 @@ export mod_sign_cmd
-
-
- ifeq ($(KBUILD_EXTMOD),)
- -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
- +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ graphene/
-
- vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
- $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
- diff --git a/arch/Kconfig b/arch/Kconfig
- index 80bbb8c..ca9f9e7 100644
- --- a/arch/Kconfig
- +++ b/arch/Kconfig
- @@ -336,6 +336,10 @@ config SECCOMP_FILTER
-
- See Documentation/prctl/seccomp_filter.txt for details.
-
- +# Used by archs to tell that they support SECCOMP_FILTER_JIT
- +config HAVE_SECCOMP_FILTER_JIT
- + bool
- +
- config HAVE_CC_STACKPROTECTOR
- bool
- help
- diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
- index 0af5250..0c4dfea 100644
- --- a/arch/x86/Kconfig
- +++ b/arch/x86/Kconfig
- @@ -94,6 +94,7 @@ config X86
- select GENERIC_CLOCKEVENTS_MIN_ADJUST
- select IRQ_FORCED_THREADING
- select HAVE_BPF_JIT if X86_64
- + select HAVE_SECCOMP_FILTER_JIT if X86_64
- select HAVE_ARCH_TRANSPARENT_HUGEPAGE
- select CLKEVT_I8253
- select ARCH_HAVE_NMI_SAFE_CMPXCHG
- @@ -1601,6 +1602,16 @@ config SECCOMP
-
- If unsure, say Y. Only embedded should say N here.
-
- +if SECCOMP
- +config SECCOMP_FILTER_JIT
- + bool "Enable seccomp filter Just In Time compiler"
- + depends on HAVE_SECCOMP_FILTER_JIT
- + depends on MODULES
- + ---help---
- + Like Berkeley Packet Filter, This option allows kernel to generate a
- + native code when seccomp filter is loaded in memory.
- +endif
- +
- source kernel/Kconfig.hz
-
- config KEXEC
- diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
- index 4ed75dd..5768520 100644
- --- a/arch/x86/net/bpf_jit_comp.c
- +++ b/arch/x86/net/bpf_jit_comp.c
- @@ -13,6 +13,7 @@
- #include <linux/filter.h>
- #include <linux/if_vlan.h>
- #include <linux/random.h>
- +#include <asm/syscall.h>
-
- /*
- * Conventions :
- @@ -108,9 +109,13 @@ do { \
- goto cond_branch
-
-
- -#define SEEN_DATAREF 1 /* might call external helpers */
- -#define SEEN_XREG 2 /* ebx is used */
- -#define SEEN_MEM 4 /* use mem[] for temporary storage */
- +#define SEEN_DATAREF (1 << 0) /* might call external skb helpers */
- +#define SEEN_XREG (1 << 1) /* ebx is used */
- +#define SEEN_MEM (1 << 2) /* use mem[] for temporary storage */
- +#define SEEN_SKBREF (1 << 3) /* use pointer to skb */
- +#define SEEN_SECCOMP (1 << 4) /* seccomp filters */
- +
- +#define NEED_PERILOGUE(_seen) ((_seen) & (SEEN_XREG | SEEN_MEM | SEEN_DATAREF))
-
- static inline void bpf_flush_icache(void *start, void *end)
- {
- @@ -122,6 +127,25 @@ static inline void bpf_flush_icache(void *start, void *end)
- set_fs(old_fs);
- }
-
- +/* helper to find the offset in struct seccomp_data */
- +#define BPF_DATA(_name) offsetof(struct seccomp_data, _name)
- +
- +/* helper to find the negative offset from the end of struct pt_regs */
- +#define roffsetof(_type, _member) ((int)(offsetof(_type, _member) - sizeof(_type)))
- +#define PT_REGS(_name) roffsetof(struct pt_regs, _name)
- +
- +#define EMIT_REGS_LOAD(offset) \
- +do { \
- + if (is_imm8(offset)) { \
- + /* mov off8(%r8),%eax */ \
- + EMIT4(0x41, 0x8b, 0x40, offset); \
- + } else { \
- + /* mov off32(%r8),%eax */ \
- + EMIT3(0x41, 0x8b, 0x80); \
- + EMIT(offset, 4); \
- + } \
- +} while (0)
- +
- #define CHOOSE_LOAD_FUNC(K, func) \
- ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
-
- @@ -178,7 +202,7 @@ static struct bpf_binary_header *bpf_alloc_binary(unsigned int proglen,
- return header;
- }
-
- -void bpf_jit_compile(struct sk_filter *fp)
- +static void *__bpf_jit_compile(struct sock_filter *filter, unsigned int flen, u8 seen_all)
- {
- u8 temp[64];
- u8 *prog;
- @@ -192,15 +216,14 @@ void bpf_jit_compile(struct sk_filter *fp)
- int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
- unsigned int cleanup_addr; /* epilogue code offset */
- unsigned int *addrs;
- - const struct sock_filter *filter = fp->insns;
- - int flen = fp->len;
- + void *bpf_func = NULL;
-
- if (!bpf_jit_enable)
- - return;
- + return bpf_func;
-
- addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL);
- if (addrs == NULL)
- - return;
- + return NULL;
-
- /* Before first pass, make a rough estimation of addrs[]
- * each bpf instruction is translated to less than 64 bytes
- @@ -212,12 +235,12 @@ void bpf_jit_compile(struct sk_filter *fp)
- cleanup_addr = proglen; /* epilogue address */
-
- for (pass = 0; pass < 10; pass++) {
- - u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
- + u8 seen_or_pass0 = (pass == 0) ? seen_all : seen;
- /* no prologue/epilogue for trivial filters (RET something) */
- proglen = 0;
- prog = temp;
-
- - if (seen_or_pass0) {
- + if (NEED_PERILOGUE(seen_or_pass0)) {
- EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
- EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
- /* note : must save %rbx in case bpf_error is hit */
- @@ -260,6 +283,47 @@ void bpf_jit_compile(struct sk_filter *fp)
- }
- }
-
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + /* For seccomp filters, load :
- + * r9 = current
- + * r8 = current->thread.sp0
- + * edi = task_thread_info(current)->status & TS_COMPAT
- + *
- + * r8 points to the end of struct pt_regs, task_pt_regs(current) + 1
- + */
- + if (seen_or_pass0 & SEEN_SECCOMP) {
- + /* seccomp filters: skb must be NULL */
- + if (seen_or_pass0 & (SEEN_SKBREF | SEEN_DATAREF)) {
- + pr_err_once("seccomp filters shouldn't use skb");
- + goto out;
- + }
- + /* r9 = current */
- + EMIT1(0x65);EMIT4(0x4c, 0x8b, 0x0c, 0x25); /* mov %gs:imm32,%r9 */
- + EMIT((u32)(unsigned long)¤t_task, 4);
- +
- + /* r8 = current->thread.sp0 */
- + EMIT3(0x4d, 0x8b, 0x81); /* mov off32(%r9),%r8 */
- + EMIT(offsetof(struct task_struct, thread.sp0), 4);
- +
- + /* edi = task_thread_info(current)->status & TS_COMPAT */
- +#ifdef CONFIG_IA32_EMULATION
- + /* task_thread_info(current): current->stack */
- + BUILD_BUG_ON(!is_imm8(offsetof(struct task_struct, stack)));
- + /* mov off8(%r9),%rdi */
- + EMIT4(0x49, 0x8b, 0x79, offsetof(struct task_struct, stack));
- + /* task_thread_info(current)->status */
- + BUILD_BUG_ON(!is_imm8(offsetof(struct thread_info, status)));
- + BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, status) != 4);
- + /* mov off8(%rdi),%edi */
- + EMIT3(0x8b, 0x7f, offsetof(struct thread_info, status));
- + /* task_thread_info(current)->status & TS_COMPAT */
- + BUILD_BUG_ON(!is_imm8(TS_COMPAT));
- + /* and imm8,%edi */
- + EMIT3(0x83, 0xe7, TS_COMPAT);
- +#endif /* CONFIG_IA32_EMULATION */
- + }
- +#endif /* CONFIG_SECCOMP_FILTER_JIT */
- +
- switch (filter[0].code) {
- case BPF_S_RET_K:
- case BPF_S_LD_W_LEN:
- @@ -272,6 +336,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- case BPF_S_ANC_VLAN_TAG_PRESENT:
- case BPF_S_ANC_QUEUE:
- case BPF_S_ANC_PKTTYPE:
- + case BPF_S_ANC_SECCOMP_LD_W:
- case BPF_S_LD_W_ABS:
- case BPF_S_LD_H_ABS:
- case BPF_S_LD_B_ABS:
- @@ -449,7 +514,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- }
- /* fallinto */
- case BPF_S_RET_A:
- - if (seen_or_pass0) {
- + if (NEED_PERILOGUE(seen_or_pass0)) {
- if (i != flen - 1) {
- EMIT_JMP(cleanup_addr - addrs[i]);
- break;
- @@ -499,6 +564,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- break;
- case BPF_S_LD_W_LEN: /* A = skb->len; */
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, len)))
- /* mov off8(%rdi),%eax */
- EMIT3(0x8b, 0x47, offsetof(struct sk_buff, len));
- @@ -508,7 +574,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- }
- break;
- case BPF_S_LDX_W_LEN: /* X = skb->len; */
- - seen |= SEEN_XREG;
- + seen |= SEEN_XREG | SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, len)))
- /* mov off8(%rdi),%ebx */
- EMIT3(0x8b, 0x5f, offsetof(struct sk_buff, len));
- @@ -519,6 +585,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- break;
- case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, protocol))) {
- /* movzwl off8(%rdi),%eax */
- EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, protocol));
- @@ -529,6 +596,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- EMIT2(0x86, 0xc4); /* ntohs() : xchg %al,%ah */
- break;
- case BPF_S_ANC_IFINDEX:
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, dev))) {
- /* movq off8(%rdi),%rax */
- EMIT4(0x48, 0x8b, 0x47, offsetof(struct sk_buff, dev));
- @@ -544,6 +612,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- break;
- case BPF_S_ANC_MARK:
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, mark))) {
- /* mov off8(%rdi),%eax */
- EMIT3(0x8b, 0x47, offsetof(struct sk_buff, mark));
- @@ -554,6 +623,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- break;
- case BPF_S_ANC_RXHASH:
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, rxhash))) {
- /* mov off8(%rdi),%eax */
- EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash));
- @@ -564,6 +634,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- break;
- case BPF_S_ANC_QUEUE:
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, queue_mapping))) {
- /* movzwl off8(%rdi),%eax */
- EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, queue_mapping));
- @@ -583,6 +654,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- case BPF_S_ANC_VLAN_TAG:
- case BPF_S_ANC_VLAN_TAG_PRESENT:
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
- + seen |= SEEN_SKBREF;
- if (is_imm8(offsetof(struct sk_buff, vlan_tci))) {
- /* movzwl off8(%rdi),%eax */
- EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, vlan_tci));
- @@ -604,6 +676,7 @@ void bpf_jit_compile(struct sk_filter *fp)
-
- if (off < 0)
- goto out;
- + seen |= SEEN_SKBREF;
- if (is_imm8(off)) {
- /* movzbl off8(%rdi),%eax */
- EMIT4(0x0f, 0xb6, 0x47, off);
- @@ -617,7 +690,7 @@ void bpf_jit_compile(struct sk_filter *fp)
- }
- case BPF_S_LD_W_ABS:
- func = CHOOSE_LOAD_FUNC(K, sk_load_word);
- -common_load: seen |= SEEN_DATAREF;
- +common_load: seen |= SEEN_SKBREF | SEEN_DATAREF;
- t_offset = func - (image + addrs[i]);
- EMIT1_off32(0xbe, K); /* mov imm32,%esi */
- EMIT1_off32(0xe8, t_offset); /* call */
- @@ -630,14 +703,14 @@ common_load: seen |= SEEN_DATAREF;
- goto common_load;
- case BPF_S_LDX_B_MSH:
- func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
- - seen |= SEEN_DATAREF | SEEN_XREG;
- + seen |= SEEN_XREG | SEEN_SKBREF | SEEN_DATAREF;
- t_offset = func - (image + addrs[i]);
- EMIT1_off32(0xbe, K); /* mov imm32,%esi */
- EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
- break;
- case BPF_S_LD_W_IND:
- func = sk_load_word;
- -common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
- +common_load_ind: seen |= SEEN_XREG | SEEN_SKBREF | SEEN_DATAREF;
- t_offset = func - (image + addrs[i]);
- if (K) {
- if (is_imm8(K)) {
- @@ -725,6 +798,72 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
- }
- EMIT_COND_JMP(f_op, f_offset);
- break;
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + case BPF_S_ANC_SECCOMP_LD_W:
- + seen |= SEEN_SECCOMP;
- + if (K == BPF_DATA(nr)) {
- + /* A = task_pt_regs(current)->orig_ax */
- + EMIT_REGS_LOAD(PT_REGS(orig_ax));
- + break;
- + }
- + if (K == BPF_DATA(arch)) {
- + /* A = AUDIT_ARCH_X86_64 */
- + EMIT1_off32(0xb8, AUDIT_ARCH_X86_64); /* mov imm32,%eax */
- +#ifdef CONFIG_IA32_EMULATION
- + /* A = compat ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64 */
- + EMIT1_off32(0xb9, AUDIT_ARCH_I386); /* mov imm32,%ecx */
- + EMIT2(0x85, 0xff); /* test %edi,%edi */
- + EMIT3(0x0f, 0x45, 0xc1); /* cmovne %ecx,%eax*/
- +#endif /* CONFIG_IA32_EMULATION */
- + break;
- + }
- + if (K >= BPF_DATA(args[0]) && K < BPF_DATA(args[6])) {
- + int arg = (K - BPF_DATA(args[0])) / sizeof(u64);
- + int off = K % sizeof(u64);
- +
- + switch (arg) {
- + case 0: off += PT_REGS(di); break;
- + case 1: off += PT_REGS(si); break;
- + case 2: off += PT_REGS(dx); break;
- + case 3: off += PT_REGS(r10); break;
- + case 4: off += PT_REGS(r8); break;
- + case 5: off += PT_REGS(r9); break;
- + }
- + EMIT_REGS_LOAD(off);
- +#ifdef CONFIG_IA32_EMULATION
- + off = K % sizeof(u64);
- + switch (arg) {
- + case 0: off += PT_REGS(bx); break;
- + case 1: off += PT_REGS(cx); break;
- + case 2: off += PT_REGS(dx); break;
- + case 3: off += PT_REGS(si); break;
- + case 4: off += PT_REGS(di); break;
- + case 5: off += PT_REGS(bp); break;
- + }
- + if (is_imm8(off)) {
- + /* mov off8(%r8),%ecx */
- + EMIT4(0x41, 0x8b, 0x48, off);
- + } else {
- + /* mov off32(%r8),%ecx */
- + EMIT3(0x41, 0x8b, 0x88);
- + EMIT(off, 4);
- + }
- + EMIT2(0x85, 0xff); /* test %edi,%edi */
- + EMIT3(0x0f, 0x45, 0xc1); /* cmovne %ecx,%eax*/
- +#endif /* CONFIG_IA32_EMULATION */
- + break;
- + }
- + if (K == BPF_DATA(instruction_pointer)) {
- + /* A = task_pt_regs(current)->ip */
- + EMIT_REGS_LOAD(PT_REGS(ip));
- + break;
- + }
- + if (K == BPF_DATA(instruction_pointer) + sizeof(u32)) {
- + EMIT_REGS_LOAD(PT_REGS(ip) + 4);
- + break;
- + }
- + goto out;
- +#endif /* CONFIG_SECCOMP_FILTER_JIT */
- default:
- /* hmm, too complex filter, give up with jit compiler */
- goto out;
- @@ -732,10 +871,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
- ilen = prog - temp;
- if (image) {
- if (unlikely(proglen + ilen > oldproglen)) {
- - pr_err("bpb_jit_compile fatal error\n");
- - kfree(addrs);
- + pr_err("bpf_jit_compile fatal error\n");
- module_free(NULL, header);
- - return;
- + goto out;
- }
- memcpy(image + proglen, temp, ilen);
- }
- @@ -747,7 +885,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
- * use it to give the cleanup instruction(s) addr
- */
- cleanup_addr = proglen - 1; /* ret */
- - if (seen_or_pass0)
- + if (NEED_PERILOGUE(seen_or_pass0))
- cleanup_addr -= 1; /* leaveq */
- if (seen_or_pass0 & SEEN_XREG)
- cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
- @@ -771,11 +909,11 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
- if (image) {
- bpf_flush_icache(header, image + proglen);
- set_memory_ro((unsigned long)header, header->pages);
- - fp->bpf_func = (void *)image;
- + bpf_func = (void *)image;
- }
- out:
- kfree(addrs);
- - return;
- + return bpf_func;
- }
-
- static void bpf_jit_free_deferred(struct work_struct *work)
- @@ -798,3 +936,38 @@ void bpf_jit_free(struct sk_filter *fp)
- kfree(fp);
- }
- }
- +
- +void bpf_jit_compile(struct sk_filter *fp)
- +{
- + u8 seen_all = SEEN_XREG | SEEN_MEM | SEEN_SKBREF | SEEN_DATAREF;
- + void *bpf_func = __bpf_jit_compile(fp->insns, fp->len, seen_all);
- +
- + if (bpf_func)
- + fp->bpf_func = bpf_func;
- +}
- +
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- +void seccomp_jit_compile(struct seccomp_filter *fp)
- +{
- + struct sock_filter *filter = seccomp_filter_get_insns(fp);
- + unsigned int flen = seccomp_filter_get_len(fp);
- + u8 seen_all = SEEN_XREG | SEEN_MEM | SEEN_SECCOMP;
- + void *bpf_func = __bpf_jit_compile(filter, flen, seen_all);
- +
- + if (bpf_func)
- + seccomp_filter_set_bpf_func(fp, bpf_func);
- +}
- +
- +void seccomp_jit_free(struct seccomp_filter *fp)
- +{
- + void *bpf_func = seccomp_filter_get_bpf_func(fp);
- +
- + if (bpf_func) {
- + unsigned long addr = (unsigned long)bpf_func & PAGE_MASK;
- + struct bpf_binary_header *header = (void *)addr;
- +
- + set_memory_rw(addr, header->pages);
- + module_free(NULL, header);
- + }
- +}
- +#endif /* CONFIG_SECCOMP_FILTER_JIT */
- diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
- index 3737f72..f7a4aba 100644
- --- a/include/linux/miscdevice.h
- +++ b/include/linux/miscdevice.h
- @@ -3,6 +3,7 @@
- #include <linux/major.h>
- #include <linux/list.h>
- #include <linux/types.h>
- +#include <../graphene/graphene.h>
-
- /*
- * These allocations are managed by device@lanana.org. If you use an
- diff --git a/include/linux/sched.h b/include/linux/sched.h
- index a781dec..3381137 100644
- --- a/include/linux/sched.h
- +++ b/include/linux/sched.h
- @@ -1161,6 +1161,11 @@ enum perf_event_task_context {
- perf_nr_task_contexts,
- };
-
- +#ifdef CONFIG_GRAPHENE
- +# include <../graphene/graphene.h>
- +struct graphene_struct;
- +#endif
- +
- struct task_struct {
- volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
- void *stack;
- @@ -1581,6 +1586,11 @@ struct task_struct {
- unsigned int sequential_io;
- unsigned int sequential_io_avg;
- #endif
- +
- +#ifdef CONFIG_GRAPHENE
- + /* for graphene tasks */
- + struct graphene_struct *graphene; /* structure to store graphene info */
- +#endif
- };
-
- /* Future-safe accessor for struct task_struct's cpus_allowed. */
- diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
- index 6f19cfd..ed258f4 100644
- --- a/include/linux/seccomp.h
- +++ b/include/linux/seccomp.h
- @@ -77,6 +77,14 @@ static inline int seccomp_mode(struct seccomp *s)
- extern void put_seccomp_filter(struct task_struct *tsk);
- extern void get_seccomp_filter(struct task_struct *tsk);
- extern u32 seccomp_bpf_load(int off);
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- +struct sock_filter *seccomp_filter_get_insns(struct seccomp_filter *);
- +unsigned int seccomp_filter_get_len(struct seccomp_filter *);
- +void *seccomp_filter_get_bpf_func(struct seccomp_filter *);
- +void seccomp_filter_set_bpf_func(struct seccomp_filter *, void *);
- +void seccomp_jit_compile(struct seccomp_filter *fp);
- +void seccomp_jit_free(struct seccomp_filter *fp);
- +#endif
- #else /* CONFIG_SECCOMP_FILTER */
- static inline void put_seccomp_filter(struct task_struct *tsk)
- {
- diff --git a/kernel/fork.c b/kernel/fork.c
- index a17621c..41d5958 100644
- --- a/kernel/fork.c
- +++ b/kernel/fork.c
- @@ -11,6 +11,7 @@
- * management can be a bitch. See 'mm/memory.c': 'copy_page_range()'
- */
-
- +#include <linux/version.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/unistd.h>
- @@ -84,6 +85,10 @@
- #define CREATE_TRACE_POINTS
- #include <trace/events/task.h>
-
- +#ifdef CONFIG_GRAPHENE
- +# include <../graphene/graphene.h>
- +#endif
- +
- /*
- * Protected counters by write_lock_irq(&tasklist_lock)
- */
- @@ -242,6 +247,10 @@ void __put_task_struct(struct task_struct *tsk)
- delayacct_tsk_free(tsk);
- put_signal_struct(tsk->signal);
-
- +#ifdef CONFIG_GRAPHENE
- + put_graphene_struct(tsk);
- +#endif
- +
- if (!profile_handoff_task(tsk))
- free_task(tsk);
- }
- @@ -322,6 +331,16 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
- tsk->stack_canary = get_random_int();
- #endif
-
- +#ifdef CONFIG_GRAPHENE
- + err = dup_graphene_struct(tsk);
- + if (err)
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
- + goto free_ti;
- +#else
- + goto out;
- +#endif
- +#endif
- +
- /*
- * One for us, one for whoever does the "release_task()" (usually
- * parent)
- diff --git a/kernel/seccomp.c b/kernel/seccomp.c
- index b7a1004..5def696 100644
- --- a/kernel/seccomp.c
- +++ b/kernel/seccomp.c
- @@ -55,9 +55,34 @@ struct seccomp_filter {
- atomic_t usage;
- struct seccomp_filter *prev;
- unsigned short len; /* Instruction count */
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + void *bpf_func;
- +#endif
- struct sock_filter insns[];
- };
-
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- +struct sock_filter *seccomp_filter_get_insns(struct seccomp_filter *fp)
- +{
- + return fp->insns;
- +}
- +
- +unsigned int seccomp_filter_get_len(struct seccomp_filter *fp)
- +{
- + return fp->len;
- +}
- +
- +void *seccomp_filter_get_bpf_func(struct seccomp_filter *fp)
- +{
- + return fp->bpf_func;
- +}
- +
- +void seccomp_filter_set_bpf_func(struct seccomp_filter *fp, void *bpf_func)
- +{
- + fp->bpf_func = bpf_func;
- +}
- +#endif
- +
- /* Limit any path through the tree to 256KB worth of instructions. */
- #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
-
- @@ -213,7 +238,16 @@ static u32 seccomp_run_filters(int syscall)
- * value always takes priority (ignoring the DATA).
- */
- for (f = current->seccomp.filter; f; f = f->prev) {
- - u32 cur_ret = sk_run_filter(NULL, f->insns);
- + u32 cur_ret;
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + void * bpf_func = seccomp_filter_get_bpf_func(f);
- + if (bpf_func)
- + cur_ret = (*(unsigned int (*)(const struct sk_buff *,
- + const struct sock_filter *))
- + bpf_func) (NULL, f->insns);
- + else
- +#endif
- + cur_ret = sk_run_filter(NULL, f->insns);
- if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION))
- ret = cur_ret;
- }
- @@ -275,6 +309,10 @@ static long seccomp_attach_filter(struct sock_fprog *fprog)
- if (ret)
- goto fail;
-
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + seccomp_jit_compile(filter);
- +#endif
- +
- /*
- * If there is an existing filter, make it the prev and don't drop its
- * task reference.
- @@ -332,6 +370,9 @@ void put_seccomp_filter(struct task_struct *tsk)
- while (orig && atomic_dec_and_test(&orig->usage)) {
- struct seccomp_filter *freeme = orig;
- orig = orig->prev;
- +#ifdef CONFIG_SECCOMP_FILTER_JIT
- + seccomp_jit_free(freeme);
- +#endif
- kfree(freeme);
- }
- }
- diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
- index 4257b7e..b21c19d 100644
- --- a/security/apparmor/lsm.c
- +++ b/security/apparmor/lsm.c
- @@ -36,6 +36,10 @@
- #include "include/policy.h"
- #include "include/procattr.h"
-
- +#ifdef CONFIG_GRAPHENE
- +# include <../graphene/graphene.h>
- +#endif
- +
- /* Flag indicating whether initialization completed */
- int apparmor_initialized __initdata;
-
- @@ -165,6 +169,12 @@ static int common_perm(int op, struct path *path, u32 mask,
- struct aa_profile *profile;
- int error = 0;
-
- +#ifdef CONFIG_GRAPHENE
- + if (GRAPHENE_ENABLED() &&
- + (error = graphene_common_perm(op, path, mask)))
- + return error;
- +#endif
- +
- profile = __aa_current_profile();
- if (!unconfined(profile))
- error = aa_path_perm(op, profile, path, 0, mask, cond);
- @@ -377,6 +387,7 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
- {
- struct aa_file_cxt *fcxt = file->f_security;
- struct aa_profile *profile;
- + u32 mask;
- int error = 0;
-
- if (!mediated_filesystem(file_inode(file)))
- @@ -388,10 +399,21 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
- * actually execute the image.
- */
- if (current->in_execve) {
- +#ifdef CONFIG_GRAPHENE
- + if (GRAPHENE_ENABLED() && (error = graphene_execve_open(file)))
- + return error;
- +#endif
- fcxt->allow = MAY_EXEC | MAY_READ | AA_EXEC_MMAP;
- return 0;
- }
-
- +#ifdef CONFIG_GRAPHENE
- + mask = aa_map_file_to_perms(file);
- + if (GRAPHENE_ENABLED() &&
- + (error = graphene_common_perm(OP_OPEN, &file->f_path, mask)))
- + return error;
- +#endif
- +
- profile = aa_cred_profile(cred);
- if (!unconfined(profile)) {
- struct inode *inode = file_inode(file);
- @@ -647,6 +669,14 @@ static struct security_operations apparmor_ops = {
- .getprocattr = apparmor_getprocattr,
- .setprocattr = apparmor_setprocattr,
-
- +#ifdef CONFIG_GRAPHENE
- + .socket_bind = graphene_socket_bind,
- + .socket_listen = graphene_socket_listen,
- + .socket_connect = graphene_socket_connect,
- + .socket_sendmsg = graphene_socket_sendmsg,
- + .socket_recvmsg = graphene_socket_recvmsg,
- +#endif
- +
- .cred_alloc_blank = apparmor_cred_alloc_blank,
- .cred_free = apparmor_cred_free,
- .cred_prepare = apparmor_cred_prepare,
- @@ -658,6 +688,10 @@ static struct security_operations apparmor_ops = {
- .bprm_secureexec = apparmor_bprm_secureexec,
-
- .task_setrlimit = apparmor_task_setrlimit,
- +
- +#ifdef CONFIG_GRAPHENE
- + .task_kill = graphene_task_kill,
- +#endif
- };
-
- /*
|