Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/xattr.h>
- #include <linux/init.h>
- #include <linux/kd.h>
- #include <linux/kernel.h>
- #include <linux/tracehook.h>
- #include <linux/errno.h>
- #include <linux/ext2_fs.h>
- #include <linux/sched.h>
- #include <linux/security.h>
- #include <linux/xattr.h>
- #include <linux/capability.h>
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/mman.h>
- #include <linux/slab.h>
- #include <linux/pagemap.h>
- #include <linux/proc_fs.h>
- #include <linux/swap.h>
- #include <linux/spinlock.h>
- #include <linux/syscalls.h>
- #include <linux/dcache.h>
- #include <linux/file.h>
- #include <linux/fdtable.h>
- #include <linux/namei.h>
- #include <linux/mount.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/netfilter_ipv6.h>
- #include <linux/tty.h>
- #include <net/icmp.h>
- #include <net/ip.h> /* for local_port_range[] */
- #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
- #include <net/inet_connection_sock.h>
- #include <net/net_namespace.h>
- #include <net/netlabel.h>
- #include <linux/uaccess.h>
- #include <asm/ioctls.h>
- #include <linux/atomic.h>
- #include <linux/bitops.h>
- #include <linux/interrupt.h>
- #include <linux/netdevice.h> /* for network interface checks */
- #include <linux/netlink.h>
- #include <linux/tcp.h>
- #include <linux/udp.h>
- #include <linux/dccp.h>
- #include <linux/quota.h>
- #include <linux/un.h> /* for Unix socket types */
- #include <net/af_unix.h> /* for Unix socket types */
- #include <linux/parser.h>
- #include <linux/nfs_mount.h>
- #include <net/ipv6.h>
- #include <linux/hugetlb.h>
- #include <linux/personality.h>
- #include <linux/audit.h>
- #include <linux/string.h>
- #include <linux/selinux.h>
- #include <linux/mutex.h>
- #include <linux/posix-timers.h>
- #include <linux/syslog.h>
- #include <linux/user_namespace.h>
- #include <linux/export.h>
- #include <linux/list.h>
- #include <linux/binfmts.h>
- #ifdef CONFIG_SECURITY_COMPSEC
- struct file_accesses {
- unsigned int read;
- unsigned int write;
- };
- extern struct security_operations *security_ops;
- static int compsec_file_permission(struct file *file, int mask)
- {
- unsigned int fclass = 0; //file security class
- unsigned int pclass = 0; // current process class
- struct inode *inode = NULL;
- char* fname = NULL;
- char* pname = NULL;
- if (!current)
- return 0;
- if (current->pid == 1 || current->pid == 0 )
- return 0;
- if (!file)
- return 0;
- if (!(file->f_path.dentry))
- return 0;
- if (!(file->f_path.dentry->d_inode))
- return 0;
- if (!(file->f_path.dentry->d_name.name))
- return 0;
- inode = file->f_path.dentry->d_inode; //file inode struct
- fname = file->f_path.dentry->d_name.name; //file basename
- if (!current_cred())
- return 0;
- if (!(current_cred()->security))
- return 0;
- pclass = (unsigned int) current_cred()->security;
- if (!(file->f_dentry))
- return 0;
- if (!(file->f_dentry->d_iname))
- return 0;
- if (inode->i_rdev || strlen(file->f_dentry->d_iname) == 0)
- return 0;
- if (current->mm)
- pname = current->mm->exe_file->f_path.dentry->d_name.name; // Getting the file assocoated to the executing process
- else
- return 0;
- int error = vfs_getxattr(file->f_path.dentry,"security.classification",&fclass,sizeof(unsigned int));//TODO: Get EA of "security.class" from the requested file - use vfs_getxattr**
- if (error == -34) {
- }
- else {
- if (error == -61) {
- fclass = 0;
- }
- else {
- return -EACCES;
- }
- }
- if (!(inode->i_sb))
- return 0;
- if (!(inode->i_sb->s_xattr))
- return 0;
- const struct xattr_handler** curr_s_xattr = inode->i_sb->s_xattr; // Helper variable to varify filesystem of inode supports EA
- if ( mask == MAY_READ ) {
- // Can read by DAC access...
- if (pclass < fclass)
- {
- if (curr_s_xattr == 0 || error == -EOPNOTSUPP)
- return 0; // The filesystem of the process doesnt support EA, skip that...
- printk("compsec: Read Access Denied for Process %s security.class=%u to file %s with security.class=%u\n", pname, pclass, fname, fclass);
- // return 0; //uncomment for debug
- return -1;
- }
- else {
- printk("compsec: Read Access for Process %s security.class=%u to file %s with security.class=%u\n", pname, pclass, fname, fclass);
- return 1;
- }
- }
- if ( mask == MAY_WRITE ) {
- // Can write by DAC access...
- if (pclass > fclass){
- char test_buffer[PATH_MAX];
- int test_buffer_len = PATH_MAX;
- char* test_path=dentry_path_raw(file->f_path.dentry,test_buffer,test_buffer_len); // Helper function for debug printing path of the executable file, and validating it is not the login record...
- if (curr_s_xattr == 0 || error == -EOPNOTSUPP || strcmp(test_path,"/utmp") == 0)
- return 0; // The filesystem of the process doesnt support EA or it is the login record (utmp), skip that
- printk("compsec: Write Access Denied for Process %s security.class=%u to file %s with security.class=%u\n", pname, pclass, fname, fclass);
- // return 0; //uncomment for debug
- return -1;
- }
- else {
- printk("compsec: Write Access for Process %s security.class=%u to file %s with security.class=%u\n", pname, pclass, fname, fclass);
- return 1;
- }
- }
- return 0;
- }
- static int compsec_cred_prepare(struct cred *new, const struct cred *old,
- gfp_t gfp)
- {
- new->security = old->security;
- //TODO: handle security credentials for new process by fork, call stack: fork->copy_creds->prepare_creds...
- return 0;
- }
- static int compsec_task_create(unsigned long clone_flags) {
- return 0;
- }
- static int compsec_bprm_set_creds(struct linux_binprm *bprm) {
- unsigned int fclass = 0;
- //unsigned int bclass = 0;
- //char* pname = NULL;
- //bclass = (unsigned int) bprm->cred->security;
- //pname = current->mm->exe_file->f_path.dentry->d_name.name;
- int error = vfs_getxattr(bprm->file->f_path.dentry,"security.classification",&fclass,sizeof(unsigned int));//TODO: Get EA of "security.class" from designated executable file - use vfs_getxattr
- bprm->cred->security=fclass;
- //current->security->cred=bprm->cred;
- //TODO: add handler for init
- return cap_bprm_set_creds(bprm);
- }
- static struct security_operations compsec_ops = {
- .name = "compsec",
- .file_permission = compsec_file_permission,
- .bprm_set_creds = compsec_bprm_set_creds,
- .task_create = compsec_task_create,
- .cred_prepare = compsec_cred_prepare,
- };
- static __init int compsec_init(void)
- {
- if (!security_module_enable(&compsec_ops)) {
- printk("compsec: disabled at boot. \n");
- return 0;
- }
- if (register_security(&compsec_ops))
- panic("compsec: Unable to register compsec with kernel.\n");
- else
- printk("compsec: registered with the kernel\n");
- return 0;
- }
- static void __exit compsec_exit (void)
- {
- return;
- }
- module_init (compsec_init);
- module_exit (compsec_exit);
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement