[翻译] getauxval() and the auxiliary vector

简介:

前言

英文原文:getauxval() and the auxiliary vector

该文章在2012年10月发表。


翻译

用户空间应用程序与内核之间有许多交流机制。系统调用和伪文件系统(诸如:/proc和/sys)广为人知。信号也同样广为人知;内核利用信号通知进程的各种同步或异步事件——例子:当进程尝试写一个破碎的管道或子进程终止时。


内核和用户空间交流还有许多复杂的机制。包括Linux专用的netlink socketsuser-mode helper功能。Netlink套接字为内核交换信息提供了一套套接字风格的API。user-mode helper功能允许内核自动调用用户空间的可执行文件;这个机制被用于许多地方,包括控制组的实现和piping core dumps to a user-space application


辅助向量(auxiliary vector),一个从内核到用户空间的信息交流机制,它一直保持透明。然而,在GNU C库(glibc)2.16发布版中添加了一个新的库函数”getauxval()”,这似乎在六月底,现在它已经变得更加可见。历史上,许多UNIX系统实现过辅助向量功能。本质上,它是一个键值对列表,当一个新的可执行映像被加载到进程中时被内核的ELF二进制加载器(fs/binfmt_elf.c文件,在内核源码中)构造。这个列表被放在进程地址空间的特定位置;在Linux系统上它存在于用户地址空间的高位(high end),在栈,命令行参数(argv)和环境变量(environ)的正上方(向下生长)。


输入图片说明

从描述和图表中我们可以看到,虽然在辅助向量在一定程度上被隐藏,对它的访问需要费点功夫。即使不使用新的库函数,一个应用程序想要访问辅助向量只需要获得挨着环境变量列表结尾的NULL指针的地址。而且,在shell级别(level),我们可以通过设置LD_SHOW_AUXV环境变量来查明当执行一个应用程序时提供给可执行文件的辅助向量。


$ LD_SHOW_AUXV=1 sleep 1000
AT_SYSINFO_EHDR: 0x7fff35d0d000
AT_HWCAP:        bfebfbff
AT_PAGESZ:       4096
AT_CLKTCK:       100
AT_PHDR:         0x400040
AT_PHENT:        56
AT_PHNUM:        9
AT_BASE:         0x0
AT_FLAGS:        0x0
AT_ENTRY:        0x40164c
AT_UID:          1000
AT_EUID:         1000
AT_GID:          1000
AT_EGID:         1000
AT_SECURE:       0
AT_RANDOM:       0x7fff35c2a209
AT_EXECFN:       /usr/bin/sleep
AT_PLATFORM:     x86_64


在系统中每个进程的辅助向量可以通过/proc/PID/auxv文件看到。dump的文件内容与上面命令的一致(作为八字节十进制数,用于该例子的键和值的尺寸在64位系统上),我们可以看到在向量中的键值对,下面内容中键值对均为0的行表示向量的结尾:

$ od -t d8 /proc/15558/auxv
0000000                   33      140734096265216
0000020                   16           3219913727
0000040                    6                 4096
0000060                   17                  100
0000100                    3              4194368
0000120                    4                   56
0000140                    5                    9
0000160                    7                    0
0000200                    8                    0
0000220                    9              4200012
0000240                   11                 1000
0000260                   12                 1000
0000300                   13                 1000
0000320                   14                 1000
0000340                   23                    0
0000360                   25      140734095335945
0000400                   31      140734095347689
0000420                   15      140734095335961
0000440                    0                    0
0000460


扫描用户空间内存的高位或读取/proc/PID/auxv的方法从辅助向量中取值是不优雅的。新的库函数提供了从列表中取出单个值的简单机制:



函数仅有一个参数,并返回对应的值。glibc头文件定义一个符号常量集,它们均以”AT_*”这种格式定义,将这些符号作为键传入getauxval;这些名称与执行带LD_SHOW_AUXV=1的命令时显示的字符串完全一样。


当然,现在显而易见的问题是:什么样的信息被放在辅助向量中,和谁需要这些信息?辅助向量的主要访问者是动态链接器(ld-linux.so)。在正常的方案中,内核的ELF二进制加载器通过加载可执行文件到进程的内存构造一个进程映像,同样的加载linker到内存。此时,动态链接器(dynamic linker)准备好接管加载程序需要的动态链接库的任务,移交控制程序本身的准备工作。然而,它缺少对这些任务某些至关重要的信息:程序在虚拟地址空间中的位置,和程序执行的起始地址。


理论上,内核可以提供一个系统调用动态链接器可以获得所需的信息。然而,这是一种低效的做事方式:内核的程序加载器已经拥有信息(因为它扫描了ELF二进制文件并构建了进程映像)并知道动态链接程序会需要它。而不是保留这个信息的记录,直到动态链接程序要求,内核可以简单的让它在进程映像的某个动态链接器已知的位置被获得。该位置当然保存的是辅助向量。


事实证明,内核的程序加载器拥有这些信息并且是动态链接器所需要的。By placing all of this information in the auxiliary vector, the kernel either saves the programming overhead of making this information available in some other way (e.g., by implementing a dedicated system call), or saves the dynamic linker the cost of making a system call, or both.辅助向量中的值可通过getauxval()获得,下面是该函数可传入的参数:


AT_PHDR和AT_ENTRY:这些键的值是可执行文件的ELF程序头的地址和可执行文件的入口地址。动态链接器使用这些信息执行链接并将控制权交给可执行文件。

AT_SECURE:如果这个可执行文件应该被安全地对待,内核会给这个键分配一个非零值。这个设置可以被Linux Security Module触发,but the common reason is that the kernel recognizes that the process is executing a set-user-ID or set-group-ID program.在这种情况下,动态链接器禁用某些环境变量(就如ld-linux.so(8)手册页中的描述)并且C库改变其行为的其他方面。

AT_UID, AT_EUID, AT_GID, 和 AT_EGID:这些是进程的真实和有效的用户ID和组ID。Making these values available in the vector saves the dynamic linker the cost of making system calls to determine the values.如果AT_SECURE值不可获得,动态链接器使用这些值来做出是否安全地处理可执行的决定。

AT_PAGESZ:这个值是系统页尺寸。动态链接器在链接阶段需要这个信息,并且C库在malloc函数族的实现中使用它。

AT_PLATFORM:这个值指向一个字符串,用于辨认程序运行在哪个硬件平台。在某些情况下,the dynamic linker uses this value in the interpretation of rpath values. (The ld-linux.so(8) man page describes rpath values.)

AT_SYSINFO_EHDR:这个值指向包含有Virtual Dynamic Shared Object (VDSO)的页,这是内核创建的以提供某些系统调用的快速实现。(一些VDSO的文档可在内核源文件Documentation/ABI/stable/vdso中找到)

AT_HWCAP:这个值指向一个多字节位掩码,设置指示详细的处理器能力。这个信息可以被用来提供某些库函数优化的行为。位掩码是硬件相关(例如:内核源码文件”arch/x86/include/asm/cpufeature.h”详细的讲述了Intel x86架构)。

AT_RANDOM:The value is a pointer to sixteen random bytes provided by the kernel. The dynamic linker uses this to implement a stack canary.


The precise reasons why the GNU C library developers have chosen to add the getauxval() function now are a little unclear. The commit message and NEWS file entry for the change were merely brief explanations of what the change was, rather than why it was made. The only clue provided by the implementer on the libc-alpha mailing list suggested that doing so was useful to allow for “future enhancements to the AT_ values, especially target-specific ones.” That comment, plus the observation that the glibc developers tend to be rather conservative about adding new interfaces to the ABI, suggest that that they have some interesting new user-space uses of the auxiliary vector in mind.

相关文章
|
监控 安全 Unix
UNIX域套接字(Unix Domain Socket)在安全性和隐私性
UNIX域套接字(Unix Domain Socket)在安全性和隐私性
901 2
|
11月前
|
存储 关系型数据库 分布式数据库
客户说|古茗选用阿里云PolarDB,以云端之力解锁茶饮数字化新高度
阿里云PolarDB将持续以“业务价值”为锚点,通过技术迭代与场景化解决方案,让每一笔交易更流畅,让每一份数据更智能,助力古茗实现“每天一杯喝不腻”的日常化国民茶饮愿景。
|
10月前
|
Ubuntu 物联网 Linux
探索Ubuntu的多样化版本及其独特优势
Lubuntu不仅在性能较低的电脑上能流畅运行,若你的CPU性能强劲,它更能发挥出超凡的实力。接下来,让我们对Lubuntu进行综合评价。在颜值方面,Lubuntu展现出了其独特的魅力,获得了★★★的评价。而在CPU要求上,它则显得极为宽容,只需★即可满足其需求。至此,我们对常见Ubuntu分支版本的介绍就告一段落了。
|
Android开发
Android在rootdir根目录创建自定义目录和挂载点的方法
本文介绍了在Android高通平台的根目录下创建自定义目录和挂载点的方法,通过修改Android.mk文件并使用`LOCAL_POST_INSTALL_CMD`变量在编译过程中添加目录,最终在ramdisk.img的系统根路径下成功创建了`/factory/bin`目录。
1056 11
|
人工智能 前端开发 容器
鸿蒙开发:了解Canvas绘制
本文主要简单的概述了Canvas绘制的基础知识,大家作为一个简单的了解即可,下面的几篇文章,我们会对相关的绘制再做进一步的分析,首先可以先做一个简单的总结:DrawingRenderingContext在使用上远远没有CanvasRenderingContext2D使用起来方便,比如在修改画笔的粗细,颜色等属性上,就可以体现出来。
326 6
鸿蒙开发:了解Canvas绘制
|
开发者
HarmonyOS实战:实现任意拖动的应用悬浮窗口
本文介绍了在鸿蒙系统上实现全局悬浮窗口的方法。通过创建子 Window,结合手势拖动、边界处理和窗口销毁等功能,实现一个可在任意页面悬浮、移动且不会超出边界的悬浮窗。文章详细解析了技术实现步骤,包括使用 `createSubWindow` 创建窗口、设置布局与背景、手势交互及边界计算等。此外,还提到 Window 的应用场景可扩展至自定义弹窗、Poupwindow 和 toast 等功能,为开发者提供更多可能性。
1014 0
HarmonyOS实战:实现任意拖动的应用悬浮窗口
|
安全 Linux Shell
runcon命令简介及用途
`runcon`是Linux的SELinux工具,用于在特定安全上下文中运行命令,加强进程权限控制。它允许管理员改变进程的安全上下文,提高安全性,隔离环境,并满足安全标准。命令参数如`-u`(用户),`-r`(角色),`-t`(类型)指定上下文。示例包括以非特权用户身份或特定上下文运行命令。使用时需注意确保SELinux启用,正确指定上下文,并遵循最小权限原则和定期审计。
|
开发者
FA/Stage模型:理解HarmonyOS的FA(Feature Ability)和Stage(Particle Ability)模型
【10月更文挑战第21天】HarmonyOS作为新一代的操作系统,其独特的FA(Feature Ability)和Stage(Particle Ability)模型为应用开发提供了新的视角。这两种模型分别代表了不同的应用组织方式,下面将详细解释这两种模型的概念、特点以及如何在实际开发中使用它们。
1250 4
|
Java 数据挖掘 Linux
Java中的跨平台桌面应用开发实践
Java中的跨平台桌面应用开发实践

热门文章

最新文章