当前位置:   article > 正文

Linux 驱动根据struct file获取全路径和文件名_通过文件指针得到文件路径

通过文件指针得到文件路径
Linux 驱动根据struct file获取全路径和文件名
一、背景

在对内核vfs层函数进行hook的时候,需要对struct pt_regs相关数据进行处理,插桩vfs_read/vfs_write时需要得到被读写文件的全路径或者文件名。

二、代码实现

根据拿到的struct file来获得文件名和对应的全路径。

//hook vfs_write
struct file *filep = NULL;
char *full_path, *temp;
char file_name = NULL;

filep = (struct file *)regs->di;

full_path = (char *)kmalloc(PATH_MAX, GFP_KERNEL);
if (full_path == NULL) {
    printk("%s: malloc memory failed\n", __func__);
    return -1;
}
memset(full_path, 0, PATH_MAX);

//Get file name
filename = filep->f_path.dentry->d_iname;

//Get full path
temp = dentry_path_raw(filep->f_path.dentry, full_path, PATH_MAX);
printk("%s\n", temp);

//根据file指针获取文件全路径
char *file_path(struct file *filep, char *buf, int buflen)
{
	return d_path(&filep->f_path, buf, buflen);
}
//最后要记得释放申请的内存
  • 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

dentry_path_raw()函数只能获取到挂载点之后的路径!!!d_path()才能获取全路径!!!

需要特别注意的是,d_path函数有可能返回error code,需要对返回的指针做判断,不然有可能发生非法地址访问导致内核OOPS。

//函数原型,为内核导出函数,放心使用
/**
 * d_path - return the path of a dentry
 * @path: path to report
 * @buf: buffer to return value in
 * @buflen: buffer length
 *
 * Convert a dentry into an ASCII path name. If the entry has been deleted
 * the string " (deleted)" is appended. Note that this is ambiguous.
 *
 * Returns a pointer into the buffer or an error code if the path was
 * too long. Note: Callers should use the returned pointer, not the passed
 * in buffer, to use the name! The implementation often starts at an offset
 * into the buffer, and may leave 0 bytes at the start.
 *
 * "buflen" should be positive.
 */
char *d_path(const struct path *path, char *buf, int buflen)
{
	char *res = buf + buflen;
	struct path root;
	int error;

	/*
	 * We have various synthetic filesystems that never get mounted.  On
	 * these filesystems dentries are never used for lookup purposes, and
	 * thus don't need to be hashed.  They also don't need a name until a
	 * user wants to identify the object in /proc/pid/fd/.  The little hack
	 * below allows us to generate a name for these objects on demand:
	 *
	 * Some pseudo inodes are mountable.  When they are mounted
	 * path->dentry == path->mnt->mnt_root.  In that case don't call d_dname
	 * and instead have d_path return the mounted path.
	 */
	if (path->dentry->d_op && path->dentry->d_op->d_dname &&
	    (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
		return path->dentry->d_op->d_dname(path->dentry, buf, buflen);

	rcu_read_lock();
	get_fs_root_rcu(current->fs, &root);
	error = path_with_deleted(path, &root, &res, &buflen);
	rcu_read_unlock();

	if (error < 0)
		res = ERR_PTR(error);
	return res;
}
EXPORT_SYMBOL(d_path);

//内核函数使用实例
static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
{
	char *tmp = (char *)__get_free_page(GFP_KERNEL);
	char *pathname;
	int len;

	if (!tmp)
		return -ENOMEM;

	pathname = d_path(path, tmp, PAGE_SIZE);
	len = PTR_ERR(pathname);
	if (IS_ERR(pathname))
		goto out;
	len = tmp + PAGE_SIZE - 1 - pathname;

	if (len > buflen)
		len = buflen;
	if (copy_to_user(buffer, pathname, len))
		len = -EFAULT;
 out:
	free_page((unsigned long)tmp);
	return len;
}
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
char *ret_path = NULL;
char buff[256] = {0};

ret_path = d_path(path, buff, sizeof(buff));
if (IE_ERR(ret_path) {
	pr_err("Get path failed\n");
	return -1;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/183425?site
推荐阅读
相关标签
  

闽ICP备14008679号