我做了sudo cat /proc/1/maps -vv
我试图弄清楚输出,可以看到很多共享库都按预期映射到了内存映射段。

7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0

到最后有类似的东西
7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0                          [heap]
7fff97863000-7fff97884000 rw-p 00000000 00:00 0                          [stack]
7fff97945000-7fff97946000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
vdsovsyscall是什么意思?是vsyscall内存的内核部分吗?如果有人可以在这个问题上有所启发,那就太好了。

最佳答案

vsyscall和vDSO段是用于加速Linux中某些系统调用的两种机制。例如,gettimeofday通常是通过此机制调用的。引入的第一个机制是vsyscall,它是执行特定系统调用的一种方式,该系统不需要任何实际特权级别即可运行,从而减少了系统调用的开销。在前面的示例之后,gettimeofday所需要做的就是读取内核的当前时间。有些应用程序经常调用gettimeofday(例如生成时间戳),以至于它们只关心一点点开销。为了解决此问题,内核将包含当前时间和快速gettimeofday实现的页面映射到用户空间(即,仅一个函数读取保存在vsyscall中的时间)。使用此虚拟系统调用,C库可以提供一个快速的gettimeofday,它不具有通常由经典系统调用模型INT 0x80SYSCALL引入的内核空间和用户空间之间的上下文切换所带来的开销。
但是,此vsyscall机制存在一些局限性:分配的内存很小,并且仅允许进行4次系统调用,更重要的是,由于vsyscall页的位置是静态的,因此vsyscall页在每个进程中都静态分配给了相同的地址。牢记在内核ABI中。 vsyscall的这种静态分配损害了Linux通常使用的内存空间随机化所带来的好处。攻击者通过利用堆栈溢出破坏了应用程序之后,可以使用任意参数从vsyscall页面调用系统调用。他所需要的只是系统调用的地址,因为它是静态分配的,所以很容易预测(如果您尝试再次运行命令,即使使用其他应用程序,您也会注意到vsyscall的地址不变)。
最好删除vsyscall页面的位置或至少对其进行随机化以阻止此类攻击。不幸的是,应用程序取决于该页面的存在和确切地址,因此无法执行任何操作。
通过使用特殊的陷阱指令替换固定地址处的所有系统调用指令,已解决了此安全问题。尝试调用vsyscall页面的应用程序将陷入内核,然后内核将在内核空间中模拟所需的虚拟系统调用。结果是内核系统调用模拟了一个虚拟系统调用,该虚拟系统调用被放置在此处以避免内核系统调用首先出现。结果是vsyscall花费了更长的执行时间,但至关重要的是,它不会破坏现有的ABI。无论如何,仅当应用程序尝试使用vsyscall页面而不是vDSO时,才会看到速度下降。
vDSO提供了与vsyscall相同的功能,同时克服了其局限性。 vDSO(虚拟动态链接的共享对象)是在用户空间中分配的内存区域,以安全的方式在用户空间中公开了一些内核功能。
引入此方法是为了解决由vsyscall引起的安全威胁。
vDSO是动态分配的,可以解决安全问题,并且可以进行4个以上的系统调用。 vDSO链接通过glibc库提供。链接程序将链接glibc vDSO功能,前提是该例程具有随附的vDSO版本,例如gettimeofday。当您的程序执行时,如果您的内核不支持vDSO,则将执行传统的syscall。
积分和有用的链接:

  • Awesome tutorial, how to create your own vDSO
  • vsyscall and vDSO, nice article
  • useful article and links
  • What is linux-gate.so.1?
  • 09-06 09:19