我做了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]vdso和vsyscall是什么意思?vsyscall是内存的内核部分吗?如果有人能对这个问题有所了解,那就太好了。
发布于 2013-11-13 07:44:03
vsyscall和vDSO段是用于加速Linux中某些系统调用的两种机制。例如,gettimeofday通常通过此机制调用。引入的第一个机制是vsyscall,它被添加为一种执行特定系统调用的方法,这些系统调用不需要任何实际的特权级别即可运行,以减少系统调用开销。按照前面的示例,gettimeofday需要做的就是读取内核的当前时间。有些应用程序频繁地调用gettimeofday (例如,生成时间戳),以至于它们关心哪怕是一点点开销。为了解决这个问题,内核将一个包含当前时间的页面和一个快速的gettimeofday实现映射到用户空间(即,只是一个将节省的时间读取到vsyscall中的函数)。使用这种虚拟系统调用,C库可以提供一个快速的gettimeofday,它不具有由经典系统调用模型INT 0x80或SYSCALL通常引入的内核空间和用户空间之间的上下文切换所引入的开销。
然而,这种vsyscall机制有一些限制:分配的内存很小,只允许4个系统调用,更重要和严重的是,vsyscall页在每个进程中静态地分配到相同的地址,因为vsyscall页的位置固定在内核ABI中。vsyscall的这种静态分配损害了Linux通常使用的内存空间随机化带来的好处。攻击者通过利用堆栈溢出危害应用程序后,可以使用任意参数从vsyscall页面调用系统调用。他所需要的就是系统调用的地址,这是很容易预测的,因为它是静态分配的(如果您尝试在不同的应用程序中再次运行您的命令,您会注意到vsyscall的地址不会改变)。最好删除或至少随机化vsyscall页面的位置,以阻止这种类型的攻击。不幸的是,应用程序依赖于该页面的存在和确切地址,因此什么也做不了。
已通过将固定地址上的所有系统调用指令替换为特殊的陷阱指令来解决此安全问题。尝试调用vsyscall页面的应用程序将陷入内核,然后内核将在内核空间中模拟所需的虚拟系统调用。结果是一个内核系统调用模拟了一个虚拟系统调用,放在那里是为了避免内核系统调用。结果是一个vsyscall,它需要更长的执行时间,但至关重要的是,它不会破坏现有的ABI。在任何情况下,只有当应用程序尝试使用vsyscall页面而不是vDSO时,才会看到速度减慢。
vDSO提供了与vsyscall相同的功能,同时克服了它的局限性。vDSO (Virtual Dynamically Shared Objects,虚拟动态链接共享对象)是分配给用户空间的一个内存区域,它以一种安全的方式在用户空间暴露了一些内核功能。这是为了解决vsyscall带来的安全威胁而引入的。vDSO是动态分配的,这解决了安全问题,可以有4个以上的系统调用。vDSO链接是通过glibc库提供的。链接器将链接到glibc vDSO功能中,前提是这样的例程具有附带的vDSO版本,比如gettimeofday。当您的程序执行时,如果您的内核不支持vDSO,则将执行传统的syscall。
致谢和有用的链接:
发布于 2016-01-01 23:57:28
我只想补充一点,现在在新内核中,vDSO不仅仅用于“安全”的syscall,它还用于决定哪种syscall机制是在系统上调用syscall的首选方法。
https://stackoverflow.com/questions/19938324
复制相似问题