从sys_read分析LSM框架运行过程

sys_read实现过程

  • sys_read interface

    asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count);
    
  • read - implement

    SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
    {
        /*
        1. 文件描述符
        	struct fd { 
                struct file *file;
                unsigned int flags;
            };
        */
    	struct fd f = fdget_pos(fd); //通过文件描述符,获取fd结构体
    	ssize_t ret = -EBADF; //ssize_t -> long
    
    	if (f.file) {
            //loff_t -> long long 
    		loff_t pos = file_pos_read(f.file);  // 读取文件的偏移量
    		ret = vfs_read(f.file, buf, count, &pos);  //在@file的@pos位置,写入@count个@buf中的字符,
    		if (ret >= 0)
    			file_pos_write(f.file, pos); 
    		fdput_pos(f);
    	}
    	return ret;
    }
    
  • vfs_read

    ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
    {
    	ssize_t ret;
    	//前两个if做一些file的权限检查
    	if (!(file->f_mode & FMODE_READ))
    		return -EBADF;
    	if (!(file->f_mode & FMODE_CAN_READ))
    		return -EINVAL;
        //检查buff是否合法
    	if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
    		return -EFAULT;
    	//检查文件是否相关的权限,hook函数在里面
    	ret = rw_verify_area(READ, file, pos, count);
    	if (!ret) {
         	//检查写入长度
    		if (count > MAX_RW_COUNT)
    			count =  MAX_RW_COUNT;
            //写入数据,以及相关的属性的变化
    		ret = __vfs_read(file, buf, count, pos);
    		if (ret > 0) {
    			fsnotify_access(file);
    			add_rchar(current, ret);
    		}
    		inc_syscr(current);
    	}
    
    	return ret;
    }
    
  • rw_verify_area

    int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
    {
    	struct inode *inode;
    	loff_t pos;
    	int retval = -EINVAL;
    	//get file's inode
    	inode = file_inode(file);
        //check inode size 
    	if (unlikely((ssize_t) count < 0))
    		return retval;
    	pos = *ppos;
        //check file offset 
    	if (unlikely(pos < 0)) {
    		if (!unsigned_offsets(file))
    			return retval;
    		if (count >= -pos) /* both values are in 0..LLONG_MAX */
    			return -EOVERFLOW;
    	} else if (unlikely((loff_t) (pos + count) < 0)) {
    		if (!unsigned_offsets(file))
    			return retval;
    	}
    	//check current pos's lock
    	if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
    		retval = locks_mandatory_area(inode, file, pos, pos + count - 1,
    				read_write == READ ? F_RDLCK : F_WRLCK);
    		if (retval < 0)
    			return retval;
    	}
        //lsm relevant hook function
    	return file_permission(file,
    				read_write == READ ? MAY_READ : MAY_WRITE);
    }
    

分析Hook函数

  • 函数原型

    int file_permission(struct file *file, int mask);
    
  • 执行流程

在这里插入图片描述

  • 当Linux传统的DAC检查完以后,会检查LSM hook中定义了的检查函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值