语境:linux-5.0/Documentation/process/adding-syscalls.rst#do-not-call-system-calls-in-the-kernel
首先,内核代码不能再调用像“sys_xyzzy()”这样的函数,因为它们有错误的调用约定。
但其次,“内核数据和用户数据之间的数据访问方式可能有所不同。”
现在有一些函数可以直接替换旧的“sys_xyzzy()”调用。例如:ksys_mount()。
ksys_mount() 获取指向__user
内存的指针,就像调用 sys_mount() 所做的那样。因此,如果您向它传递一个指向内核内存的指针,它应该会失败。具体来说,当调用copy_from_user()时会失败,除非你用set_fs()玩游戏。
那么...为什么我们要在内核中的不同位置多次调用 ksys_mount() 呢?这些怎么可能起作用?它们不包含对 set_fs() 的调用。
https://elixir.bootlin.com/linux/v5.0/ident/ksys_mount
- 驱动程序/base/devtmpfs.c
- 初始化/do_mounts.c
- ...
答案1
devtmpfs
当前在内核线程中运行。在内核线程中,addr_limit
被有效禁用。至少对于 x86 来说是这样的——它是特定于体系结构的代码。
init/do_mounts.c
很相似。内核 init 进程必须像内核线程一样启动,并addr_limit
有效禁用。随后,它调用do_execve()
开始执行用户空间init程序。内核确保调用“set_fs(USER_DS)”,在执行用户空间程序之前。