对 sys_stat 感到困惑,sys_statfs 系统调用有效

问题描述 投票:0回答:1

我正在尝试在

stat
系统调用上设置 kprobe 以捕获一些信息。当检查
/proc/kallsyms
时,我有很多相似的名字,这有点令人困惑,哪个是最适合我使用的。

我正在尝试找到正确的系统调用,用于获取

stat filename
stat dir
等命令输出中显示的数据。

首先我尝试了

__x64_sys_stat
,但我的处理程序没有被调用。然后我尝试了
__do_sys_stat
__x64_sys_newstat
,但没有调用任何处理程序。

下面是

/proc/kallsyms
,

的输出
user@xubun2204:~$ cat /proc/kallsyms | grep newstat
0000000000000000 t __do_sys_newstat
0000000000000000 T __x64_sys_newstat
0000000000000000 T __ia32_sys_newstat
0000000000000000 t __do_compat_sys_newstat
0000000000000000 T __ia32_compat_sys_newstat
0000000000000000 T __x64_compat_sys_newstat
0000000000000000 d event_exit__newstat
0000000000000000 d event_enter__newstat
0000000000000000 d __syscall_meta__newstat
0000000000000000 d args__newstat
0000000000000000 d types__newstat
0000000000000000 d __event_exit__newstat
0000000000000000 d __event_enter__newstat
0000000000000000 d __p_syscall_meta__newstat
0000000000000000 d _eil_addr___x64_compat_sys_newstat
0000000000000000 d _eil_addr___ia32_compat_sys_newstat
0000000000000000 d _eil_addr___ia32_sys_newstat
0000000000000000 d _eil_addr___x64_sys_newstat
user@xubun2204:~$ cat /proc/kallsyms | grep do_stat
0000000000000000 T proc_do_static_key
0000000000000000 T do_statx
0000000000000000 t do_statfs_native
0000000000000000 t do_statfs64
user@xubun2204:~$ cat /proc/kallsyms | grep sys_stat
0000000000000000 t __do_sys_stat
0000000000000000 T __x64_sys_stat
0000000000000000 T __ia32_sys_stat
0000000000000000 T __x64_sys_statx
0000000000000000 T __ia32_sys_statx
0000000000000000 t __do_sys_statfs
0000000000000000 T __x64_sys_statfs
0000000000000000 T __ia32_sys_statfs
0000000000000000 t __do_sys_statfs64
0000000000000000 T __x64_sys_statfs64
0000000000000000 T __ia32_sys_statfs64
0000000000000000 t __do_compat_sys_statfs
0000000000000000 T __ia32_compat_sys_statfs
0000000000000000 T __x64_compat_sys_statfs
0000000000000000 T kcompat_sys_statfs64
0000000000000000 T __ia32_compat_sys_statfs64
0000000000000000 T __x64_compat_sys_statfs64
0000000000000000 d _eil_addr___ia32_sys_statx
0000000000000000 d _eil_addr___x64_sys_statx
0000000000000000 d _eil_addr___ia32_sys_stat
0000000000000000 d _eil_addr___x64_sys_stat
0000000000000000 d _eil_addr___x64_compat_sys_statfs64
0000000000000000 d _eil_addr___ia32_compat_sys_statfs64
0000000000000000 d _eil_addr___x64_compat_sys_statfs
0000000000000000 d _eil_addr___ia32_compat_sys_statfs
0000000000000000 d _eil_addr___ia32_sys_statfs64
0000000000000000 d _eil_addr___x64_sys_statfs64
0000000000000000 d _eil_addr___ia32_sys_statfs
0000000000000000 d _eil_addr___x64_sys_statfs

然后我尝试了

__x64_sys_statfs
,现在我的处理人员接到电话了!

我理解

sys_stat
sys_statfs
之间的区别的方式是
sys_stat
用于获取有关文件和目录的信息,
sys_statfs
用于获取有关文件系统的信息。

但是在这种情况下,无论我在

stat
命令行(文件系统或特定文件或目录)中经历什么,
__x64_sys_statfs
都会被调用!

当我想读取此系统调用返回的内容时,问题就开始了,我应该期待

struct kstat
还是
struct statfs

这是我设法触发 kretprobe 处理程序的代码,

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/statfs.h>
#include <linux/slab.h>
#include <linux/fs.h>

static struct kretprobe my_kretprobe;

static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    printk("entry_handler\n");
    return 0;
}

static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    printk("ret_handler\n");
    return 0;
}

static int __init my_module_init(void)
{
    int ret;

    my_kretprobe.kp.symbol_name = "__x64_sys_statfs";
    my_kretprobe.entry_handler = entry_handler;
    my_kretprobe.handler = ret_handler;
    my_kretprobe.maxactive = 20;

    ret = register_kretprobe(&my_kretprobe);
    if (ret < 0) {
        printk(KERN_INFO "register_kretprobe failed, returned %d\n", ret);
        return ret;
    }

    printk(KERN_INFO "Kretprobe registered for __x64_sys_statfs\n");
    return 0;
}

static void __exit my_module_exit(void)
{
    unregister_kretprobe(&my_kretprobe);
    printk(KERN_INFO "Kretprobe unregistered\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jelal");
MODULE_DESCRIPTION("simple kret lkm");

和 Makefile,

obj-m += statdata.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

我正在试验,我对产品没有任何最终目标,唯一的目标是能够从内核访问 stat 终端命令显示的数据。

  • sys_stat
    sys_statfs
    sys_newstat
    sys_statx
    有什么区别?
  • 我如何知道哪个系统调用是安装探针的正确系统调用?
  • sys_stat 似乎没有被使用的原因是什么?

谢谢

c linux linux-kernel kprobe
1个回答
0
投票

当您使用命令行 stat 实用程序时,是否使用取决于该实用程序的版本:

  • 系统统计,
  • 打开,然后sys_fstat,
  • sys_lstat,
  • opendir,然后 sys_newfstatat
  • sys_statx

这些都返回有关命名对象的大致相同的信息(statx 使用不同的结构),但编程输入略有不同,而命令行工具不会公开这些信息。

在许多情况下,它将是 lstat,或者标记为 NOFOLLOW 的其他调用之一,因为 stat 命令想要报告它看到了链接。确定指定的资源不是链接后,就无需再次调用 stat,但如果它是链接,则可能需要再次调用 stat。

ltrace 和 strace 是有用的工具,可以查看应用程序实际进行了哪些库和系统调用。

通常,库调用是系统调用的薄包装器,但对于 stat 系列函数来说,库入口点的名称中有一个 x,以及一个额外的参数,指定应用程序所使用的 stat 结构的版本期望。动态库实现可以选择将系统调用结果转换为结构的早期版本,或者如果版本无法识别,则使调用失败而不进行系统调用。然而,我认为这个版本控制功能从来没有真正在愤怒中被使用过。通常,库调用名称会在名称后附加 64,以支持在过渡期间使用 64 位接口的 32 位程序,这些程序现在重新编译为 64 位程序。

© www.soinside.com 2019 - 2024. All rights reserved.