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/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 #include #include +#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/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 #include #include #include @@ -84,6 +85,10 @@ #define CREATE_TRACE_POINTS #include +#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 -ruNp linux-3.19/mm/mmap.c linux-3.19.new/mm/mmap.c --- linux-3.19/mm/mmap.c 2015-02-08 21:54:22.000000000 -0500 +++ linux-3.19.new/mm/mmap.c 2016-08-23 22:15:18.387511888 -0400 @@ -2000,6 +2000,10 @@ arch_get_unmapped_area_topdown(struct fi } #endif +#ifdef CONFIG_GRAPHENE +# include <../graphene/graphene.h> +#endif + unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) @@ -2018,6 +2022,10 @@ get_unmapped_area(struct file *file, uns get_area = current->mm->get_unmapped_area; if (file && file->f_op->get_unmapped_area) get_area = file->f_op->get_unmapped_area; +#ifdef CONFIG_GRAPHENE + if (file && current->in_execve && GRAPHENE_ENABLED()) + get_area = graphene_execve_get_area; +#endif addr = get_area(file, addr, len, pgoff, flags); if (IS_ERR_VALUE(addr)) return addr; 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 }; /*