#ifndef _LINUX_GRAPHENE_H #define _LINUX_GRAPHENE_H #include #include #include #define GRAPHENE_FILE "/dev/graphene" #define GRAPHENE_MINOR 239 #define GRAPHENE_UNIX_PREFIX_FMT "/graphene/%016lx" #define GRAPHENE_MCAST_GROUP "239.0.0.1" /* symbolic link this header file in include/linux */ /* This header needs to be included in include/linux/sched.h */ #ifndef __KERNEL__ # ifdef __user # undef __user # endif # define __user #endif #define GRAPHENE_LIB_NAME 0001 #define GRAPHENE_LIB_ADDR 0002 #define GRAPHENE_UNIX_PREFIX 0003 #define GRAPHENE_MCAST_PORT 0004 #define GRAPHENE_FS_PATH 0005 #define GRAPHENE_NET_RULE 0006 #define GRAPHENE_POLICY_TYPES 0007 #define GRAPHENE_FS_RECURSIVE 0010 #define GRAPHENE_FS_READ 0020 #define GRAPHENE_FS_WRITE 0040 #define GRAPHENE_NET_BIND 0100 struct graphene_user_policy { int type; const void __user * value; }; struct graphene_net_addr { union { struct in_addr sin_addr; struct in6_addr sin6_addr; } addr; unsigned short port_begin; unsigned short port_end; }; struct graphene_net_rule { unsigned short family; struct graphene_net_addr addr; }; #define GRAPHENE_SET_TASK _IOW('k', 16, void *) struct graphene_policies { int npolicies; struct graphene_user_policy policies[]; }; #ifdef __KERNEL__ #include #include #include #include #include #include #include #include struct task_struct; struct path; struct qstr; struct graphene_path { struct list_head list; struct path path; int type; }; #define ADDR_ANY 0x1 #define PORT_ANY 0x2 struct graphene_net { struct list_head list; short family; unsigned char flags; struct graphene_net_addr addr; }; struct graphene_unix { atomic_t count; struct list_head list; struct path root; struct qstr prefix; }; /* * add the following line to struct task_struct (include/linux/sched.h): * struct graphene_struct *graphene; */ struct graphene_info { atomic_t gi_count; struct path gi_libexec; u64 gi_libaddr; struct path gi_console[3]; char gi_unix[28]; /* fmt: @/graphene/%016lx/ */ struct list_head gi_paths; struct list_head gi_rpaths; struct list_head gi_binds; struct list_head gi_peers; unsigned short gi_mcast_port; struct file * gi_mcast_sock; u64 gi_gipc_session; }; struct graphene_struct { atomic_t g_count; struct graphene_info __rcu *g_info; spinlock_t g_lock ____cacheline_aligned_in_smp; }; #define GRAPHENE_ENABLED() (current->graphene != NULL) /* use this function in __put_task_struct (kernel/fork.c) */ int dup_graphene_struct(struct task_struct *task); /* use this function in dup_task_struct (kernel/fork.c) */ void put_graphene_struct(struct task_struct *task); /* add the following lines to common_perm (security/apparmor/lsm.c): * (when current->in_execve is true) * if (GRAPHNEE_ENABLED() && (error = graphene_execve_open(file)) * return error; */ int graphene_execve_open(struct file *file); /* * add the following lines to common_perm (security/apparmor/lsm.c): * if (GRAPHENE_ENABLED() && * (error = graphene_common_perm(op, path, mask))) * return error; * * add the following lines to apparmor_dentry_open (security/apparmor/lsm.c): * if (GRAPHENE_ENABLED() && * (error = graphene_common_perm(OP_OPEN, &file->path, mask))) * return error; */ int graphene_common_perm(int op, struct path *path, u32 mask); /* * add the following lines to the initializer of apparmor_ops * (security/apparmor/lsm.c): * task_kill = graphene_task_kill, */ int graphene_task_kill(struct task_struct *task, struct siginfo *info, int sig, u32 secid); /* * add the following lines to the initializer of apparmor_ops * (security/apparmor/lsm.c): * socket_bind = graphene_socket_bind, * socket_listen = graphene_socket_listen, * socket_connect = graphene_socket_connect, * socket_sendmsg = graphene_socket_sendmsg, * socket_recvmsg = grapheen_socket_recvmsg, */ int graphene_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen); int graphene_socket_listen(struct socket *sock, int backlog); int graphene_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen); int graphene_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size); int graphene_socket_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags); u64 gipc_get_session(struct task_struct *tsk); #endif /* __KERNEL__ */ #endif