Unknown symbol security_hook_heads (err 0)

复制代码
/*

 * A LSM modules which implements role based access control.

 */

#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/ptrace.h>

#include <linux/errno.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/swap.h>

#include <linux/uaccess.h>

#include <linux/spinlock.h>

#include <linux/syscalls.h>

#include <linux/file.h>

#include <linux/namei.h>

#include <linux/mount.h>

#include <linux/ext2_fs.h>

#include <linux/proc_fs.h>

#include <linux/kd.h>

#include <linux/netfilter_ipv4.h>

#include <linux/netfilter_ipv6.h>

#include <linux/tty.h>

#include <net/icmp.h>

#include <net/ip.h>        /* for sysctl_local_port_range[] */

#include <net/tcp.h>        /* struct or_callable used in sock_rcv_skb */

#include <asm/uaccess.h>

#include <asm/ioctls.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/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/sysctl.h>

#include <linux/audit.h>

#include <linux/string.h>

#include <linux/unistd.h>

#include <linux/lsm_hooks.h>

#include <linux/syscalls.h>

#include <linux/kallsyms.h>

#include <linux/sched.h>

#include <asm/uaccess.h>

#include <asm/unistd.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/syscalls.h>

#include <linux/file.h>

#include <linux/fs.h>

#include <linux/fcntl.h>

#include <linux/version.h>

#include <linux/syscalls.h>



//定义将要hook的系统调用

#define SYSCALL_CONNECT        0x01

#define SYSCALL_SOCKET        0x02

#define SYSCALL_MKDIR        0x04

#define SYSCALL_RMDIR        0x08

#define SYSCALL_TASK_CREATE 0x10



//定义四种角色

#define ROLE_RECYCLER_NAME "recycler"

#define ROLE_OPERATOR_NAME "operator"

#define ROLE_NETMANAGER_NAME "netmanager"

#define ROLE_ADMIN_NAME "admin"



#define ROLE_RECYCLER     1

#define ROLE_OPERATOR     2

#define ROLE_NETMANAGER 3

#define ROLE_ADMIN         4



//定义几个配置文件的路径,此处是硬编码的

#define ROLE_CONFIG        "/etc/rbos/role_config"

#define USER_CONFIG        "/etc/rbos/user_config"



//最多支持16种角色,128个用户的分配

#define SAMPLE_MAX_ROLE     16

#define SAMPLE_MAX_USER        128



#define SAMPLE_MAX_BUF        1024





//角色结构

typedef struct __role__

{

    unsigned int roleid;

    unsigned int right;

}_ROLE_STRUCT;

_ROLE_STRUCT all_roles[SAMPLE_MAX_ROLE]={{0,0},};

unsigned int all_roles_cnt=0;



//用户结构

typedef struct __user__

{

    unsigned int userid;

    unsigned int right;

}_USER_STRUCT;



_USER_STRUCT all_users[SAMPLE_MAX_USER]={{0,SYSCALL_CONNECT | SYSCALL_SOCKET | SYSCALL_MKDIR |SYSCALL_RMDIR | SYSCALL_TASK_CREATE},};

unsigned int all_users_cnt=1;



typedef union {

    struct _socket_info{

        int domain;

        int type;

        int protocol;

    };

    struct _connect_info {

        struct socket *sock;

        struct sockaddr *address;

        int addrlen;

    }connect_info;

    

    struct _mkdir_info {

        struct inode *dir;

        struct dentry *dentry;

        int mask;

    }mkdir_info;

    

    struct _rmdir_info {

        struct inode *dir;

        struct dentry *dentry;

    }rmdir_info;

    struct _taskcreate_info{

        unsigned long clone_flags;

    };

}perm_info_t;





unsigned int sample_asc2int(char * str,int len)

//将整形字符串转换为整数

{

    unsigned int rst =0;

    int i;

    for(i =0;i<len;i++)

    {

        rst=rst * 10 + str[i]-'0';

    }

    printk(KERN_WARNING "asc2int::%d,len:%d  str:%s.\n",rst,len,str);

    return rst;

}

int check_connect_perm(perm_info_t *info,unsigned int right)

{

    printk(KERN_WARNING "___Check connect permission___:: %s\n", __FUNCTION__);

    if(right & SYSCALL_CONNECT) 

    {

        return 0;

    }

    else

    {

        return -EINVAL;

    }

}



int check_socket_perm(perm_info_t *info,unsigned int right)

{

    printk(KERN_WARNING "___Check socket create permission___:: %s\n", __FUNCTION__);

    if(right&SYSCALL_SOCKET)

    {

        return 0;

    }

    else

    {

        return -EINVAL;

    }

}



int check_taskcreate_perm(perm_info_t *info,unsigned int right)

{

    printk(KERN_WARNING "___Check task_create permission___:: %s\n", __FUNCTION__);

    if(right & SYSCALL_TASK_CREATE)

    {

        return 0;

    }

    else

    {

        return -EINVAL;

    }

    

}





int check_mkdir_perm(perm_info_t *info,unsigned int right)

{

    printk(KERN_WARNING "___Check mkdir permission___:: %s\n", __FUNCTION__);

    if(right & SYSCALL_MKDIR)

    {

        return 0;

    }

    else

    {

        return -EINVAL;

    }

}



int check_rmdir_perm(perm_info_t *info,unsigned int right)

{

    printk(KERN_WARNING "___Check rmdir permission___:: %s\n", __FUNCTION__);

    if(right & SYSCALL_RMDIR)

    {

        return 0;

    }

    else

    {

        return -EINVAL;

    }

}





static int check_perm(int syscall_type, perm_info_t *perm_info)

{

    int ret=0;

    struct cred * new;

    unsigned int uid=0;

    unsigned int right=0;

    

    

    //获取用户实际uid,并且得到用户的权限,默认用户都拥有SYSCALL_TASK_CREATE的权限

    //注意并没有使用有效用户id;因为有效用户id会通过setuid位升权限

    new=prepare_creds();

    uid =(unsigned int)(new->uid).val;

    int i;

    for( i=0;i<all_users_cnt;i++)

    {

        if(all_users[i].userid == uid)

        {

            right |= all_users[i].right;

            break;

        }

    }

    if(right==0)

        //非测试用户,打开所有权限

    {

        right=SYSCALL_CONNECT | SYSCALL_SOCKET | SYSCALL_MKDIR |SYSCALL_RMDIR | SYSCALL_TASK_CREATE;

    }

    printk(KERN_WARNING "____Check Permission___::%s, real uid :: %d.\n", __FUNCTION__,uid);

    switch (syscall_type) {

    case SYSCALL_CONNECT:

        ret = check_connect_perm(perm_info,right);

        break;

        

    case SYSCALL_SOCKET:

        ret = check_socket_perm(perm_info,right);

        break;



    case SYSCALL_TASK_CREATE:

        ret = check_taskcreate_perm(perm_info,right);

        break;



    case SYSCALL_MKDIR:

        ret = check_mkdir_perm(perm_info,right);

        break;



    case SYSCALL_RMDIR:

        ret = check_rmdir_perm(perm_info,right);

        break;

    }

    

    return ret;  

}



static int sample_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)

{

    perm_info_t perm_info;



    

    return check_perm(SYSCALL_CONNECT, &perm_info);

}



static int sample_socket(int domain,int type,int protocol,int kern)

//TODO 完善参数列表

{

    perm_info_t perm_info;



    return check_perm(SYSCALL_SOCKET,&perm_info);

}



static int sample_task_create(unsigned long clone_flags)

{

    perm_info_t perm_info;



    return check_perm(SYSCALL_TASK_CREATE,&perm_info);

}



static int sample_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)

{

    perm_info_t perm_info; 





    

    return check_perm(SYSCALL_MKDIR, &perm_info);

    

}



static int sample_inode_rmdir(struct inode *dir, struct dentry *dentry)

{

    perm_info_t perm_info; 





    

    return check_perm(SYSCALL_RMDIR, &perm_info);

}





static void get_role_config(void)

{

    char buf[SAMPLE_MAX_BUF]={0};

    struct file * f=NULL;

    const char * filename =ROLE_CONFIG;

    char * p;

    int i=0;

    char * line_start;

    char * token_start;

    printk(KERN_INFO "get role config from %s.\n",filename);

    mm_segment_t oldfs;



    f =filp_open(filename,O_RDONLY,0);

    if( IS_ERR(f) || (f==NULL))

    {

        printk(KERN_WARNING "get role config error.\n");

        return ;

    }

    p=buf;

    line_start = buf;

    token_start=buf;

    int role_index =0;

    oldfs =get_fs();

    //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

    set_fs(get_ds());

    //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

    while(vfs_read(f,buf+i,1,&f->f_pos)==1)

    {

        //printk(KERN_INFO "%s::%d.THE SRC:%s\n",__FUNCTION__,__LINE__,buf);

        if(i==SAMPLE_MAX_BUF)

            //读满缓存区

        {

            break;

        }

        if(buf[i]==':')

            //读到角色

        {

            //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

            buf[i]=0;//把":"截断

            printk(KERN_INFO "read a role of :%s.\n",line_start);

            

            all_roles_cnt++;

            if(role_index != 0)

            {

                printk(KERN_INFO "last role right:%x.\n",all_roles[role_index].right);

            }

            if(strcmp((const char *)line_start,ROLE_ADMIN_NAME)==0)

            {

                role_index = ROLE_ADMIN;

            }

            //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

            if(strcmp((const char *)line_start,ROLE_NETMANAGER_NAME)==0)

            {

                role_index = ROLE_NETMANAGER;

            }

            //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

            if(strcmp((const char *)line_start,ROLE_OPERATOR_NAME)==0)

            {

                role_index =ROLE_OPERATOR;

            }

            //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

            if(strcmp((const char *)line_start,ROLE_RECYCLER_NAME)==0)

            {

                role_index=ROLE_RECYCLER;

            }

            token_start = buf+i+1;

        }

        if(buf[i]=='\n')

            //遇到换行符了

        {

            line_start = buf +i +1;

        }

        //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

        if(buf[i]==',' || buf[i]==';')

            //到了一个token的终点

        {

            //[token_start,buf+i)是一个token

            buf[i]=0;

            if((buf+i-token_start)<4)

                //明显不是一个token

            {

                ;

            }

            else

            {

                

                //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

                if(strcmp((const char *)token_start,"SYSCALL_CONNECT")==0)

                    //具有SYSCALL_CONNECT权限

                {

                    all_roles[role_index].right |=SYSCALL_CONNECT;

                }

                //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

                if(strcmp((const char *)token_start,"SYSCALL_SOCKET")==0)

                {

                    all_roles[role_index].right |= SYSCALL_SOCKET;

                }

                //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

                if(strcmp((const char *)token_start,"SYSCALL_MKDIR")==0)

                {

                    all_roles[role_index].right |=SYSCALL_MKDIR;

                }

                //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

                if(strcmp((const char *)token_start,"SYSCALL_RMDIR")==0)

                {

                    all_roles[role_index].right |=SYSCALL_RMDIR;

                }

                //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

                if(strcmp((const char *)token_start,"SYSCALL_TASK_CREATE")==0)

                {

                    all_roles[role_index].right |= SYSCALL_TASK_CREATE;

                }

            }

            token_start=buf+i+1;

        }

        i++;

    }

    set_fs(oldfs);

    filp_close(f,0);



    printk(KERN_INFO "load %d roles.\n",all_roles_cnt);

}





static void get_user_config(void)

{

    char buf[SAMPLE_MAX_BUF]={0};

    struct file * f=NULL;

    const char * filename =USER_CONFIG;

    char * p;

    int i=0;

    char * line_start;

    char * token_start;

    printk(KERN_INFO "get user config from %s.\n",filename);

    mm_segment_t oldfs;



    f =filp_open(filename,O_RDONLY,0);

    if( IS_ERR(f) || (f==NULL))

    {

        printk(KERN_WARNING "get user config error.\n");

        return ;

    }

    p=buf;

    line_start = buf;

    token_start=buf;

    int user_index =0;

    oldfs =get_fs();

    //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

    set_fs(KERNEL_DS);

    //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

    while(vfs_read(f,buf+i,1,&f->f_pos)==1)

    {

        //printk(KERN_INFO "%s::%d.\n",__FUNCTION__,__LINE__);

        if(i==SAMPLE_MAX_BUF)

            //读满缓存区

        {

            break;

        }

        if(buf[i]==':')

            //读到用户了

        {

            unsigned int userid = sample_asc2int(line_start,buf+i-line_start);

            printk(KERN_INFO "read userid of %d.\n",userid);

            if(all_users_cnt)

            {

                printk(KERN_INFO "last user ::%d,right:%x.\n",all_users[all_users_cnt-1].userid,all_users[all_users_cnt-1].right);

            }

            all_users[all_users_cnt++].userid =userid;

            user_index = all_users_cnt-1;

            token_start = buf+i+1;

        }

        //TODO

        if(buf[i]=='\n')

            //遇到换行符了

        {

            line_start = buf +i +1;

        }

        if(buf[i]==',' || buf[i]==';')

            //到了一个token的终点

        {

            //[token_start,buf+i)是一个token

            buf[i]=0;

            if((buf+i-token_start)<5)

                //明显不是一个token,这有可能为空

            {

                ;

            }

            else

            {

                if(strcmp((const char *)token_start,ROLE_ADMIN_NAME)==0)

                {

                    all_users[user_index].right |=all_roles[ROLE_ADMIN].right;

                }

                if(strcmp((const char *)token_start,ROLE_OPERATOR_NAME)==0)

                {

                    all_users[user_index].right |=all_roles[ROLE_OPERATOR].right;

                }

                if(strcmp((const char *)token_start,ROLE_RECYCLER_NAME)==0)

                {

                    all_users[user_index].right |=all_roles[ROLE_RECYCLER].right;

                }

                if(strcmp((const char *)token_start,ROLE_NETMANAGER_NAME)==0)

                {

                    all_users[user_index].right |=all_roles[ROLE_NETMANAGER].right;

                }

            }

            token_start=buf+i+1;

        }

        i++;

    }

        set_fs(oldfs);

    filp_close(f,0);



    printk(KERN_INFO "load %d user.\n",all_users_cnt);

}



static struct security_hook_list demo_hooks[]=

{

    LSM_HOOK_INIT(socket_connect,sample_socket_connect),

    LSM_HOOK_INIT(socket_create,sample_socket),

    LSM_HOOK_INIT(task_create,sample_task_create),

//    LSM_HOOK_INIT(inode_mkdir,sample_inode_mkdir),

    LSM_HOOK_INIT(inode_rmdir,sample_inode_rmdir)

};





static  int sample_init(void)

{



    printk(KERN_INFO "ADD LSM SAMPLE.\n");

    printk(KERN_INFO "LOAD ROLE CONFIG.\n");//载入role config;

    get_role_config();

    printk(KERN_INFO "LOAD USER CONFIG.\n");//载入user config;

    get_user_config();

    security_add_hooks(demo_hooks,ARRAY_SIZE(demo_hooks));

    printk(KERN_INFO "Sample:  Initializing.\n");



    return 0;

}



static  void sample_exit(void)

{

    printk(KERN_INFO "Sample: Exiting.\n");    

}







module_init(sample_init);





module_exit(sample_exit);



MODULE_LICENSE("GPL");

MODULE_AUTHOR("JMH");

MODULE_DESCRIPTION("A LSM Driver implements RBAC");
复制代码

 

posted on   lydstory  阅读(346)  评论(1编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2020-04-09 Linux获得mac地址
2020-04-09 校对:思路
2020-04-09 拒绝手机浏览器短视频
2020-04-09 问题:每秒的问题
2020-04-09 黑马校对软件
2018-04-09 oepnni安装

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示