SerenityOS whoami 命令完全指南:从使用到 LibC 底层实现 SerenityOS whoami 命令完全指南从使用到 LibC 底层实现【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenitywhoami是 SerenityOS 中最基础也最常用的命令之一用于打印与当前有效 UIDEffective UID关联的用户名。本文以 whoami 手册页 为核心结合Userland/Utilities/whoami.cpp源码与 LibC 层getlogin()的实现从命令行用法、权限模型到源码级原理逐层展开读完后你不仅能熟练使用该命令还能理解 SerenityOS 中进程身份 → 用户名的完整解析链路。命令概览功能与语法手册页中对whoami的定位非常明确whoami - print effective user name打印有效用户名其语法极简不接受任何参数与选项$ whoami在 SerenityOS 中whoami的实际作用是输出与当前有效 UID相关联的用户名。这里的有效 UID与真实 UID 相对当程序以 setuid 方式运行或进程主动调用身份切换接口如setuid、seteuid后有效 UID 可能与启动时的真实 UID 不同而whoami始终以有效身份为准作答。与它功能互补的是id(1) 命令后者能够同时输出 UID、GID 及全部附加组信息。从两个手册页的 See also 交叉引用可以看出二者在 SerenityOS 的 man 体系中是一组紧密关联的身份查询工具。实战示例普通用户与超级用户手册页给出了两个典型运行场景$ whoami anon # whoami root在默认登录为anon用户的图形会话或终端中whoami输出anon对应 UID 100参见id(1) 示例中的uid100(anon)。在以rootUID 0身份运行的 Shell 中例如通过su切换或从 root 会话启动输出root。这一对比清晰展示了whoami在权限调试中的价值当不确定当前进程实际以何种身份运行、或者怀疑 setuid 程序是否生效时执行whoami即可立即得到有效身份的答案。源码实现一个极简但安全的工具whoami的实现位于 Userland/Utilities/whoami.cpp完整代码仅有十余行#include LibCore/System.h #include LibMain/Main.h #include stdio.h #include unistd.h ErrorOrint serenity_main(Main::Arguments) { TRY(Core::System::pledge(stdio rpath)); TRY(Core::System::unveil(/etc/passwd, r)); TRY(Core::System::unveil(nullptr, nullptr)); puts(getlogin()); return 0; }这段代码展示了 SerenityOS 用户态工具的标准写法其中包含三个值得深入的技术点1. 入口约定serenity_main所有 SerenityOS 用户态程序都通过LibMain提供的serenity_main作为入口而非裸的main其返回ErrorOrint使得TRY宏可以便捷地传播错误。这保证了工具在资源受限、初始化失败时能统一、干净地退出。2. 安全加固pledge 与 unveilCore::System::pledge(stdio rpath)声明该进程只承诺使用标准 I/O 与只读路径解析能力Core::System::unveil(/etc/passwd, r)将进程可访问的文件系统视野收缩到/etc/passwd这一个文件的只读访问unveil(nullptr, nullptr)用于锁定上述声明此后无法再新增任何可见路径。这两层承诺 揭幕机制是 SerenityOS 的纵深防御哲学在最小工具上的体现即使whoami被攻破攻击者能做的也仅限于读取/etc/passwd并输出文本。3. 身份查询getlogin()关键一行是puts(getlogin())。getlogin()是 LibCunistd.h提供的接口其实现位于 Userland/Libraries/LibC/unistd.cpp。从源码第 876-886 行附近可以看到它内部通过查询用户数据库getpwuid路径取得当前有效 UID 对应的passwd记录再返回其中的pw_name字段并使用静态缓冲区缓存结果static OptionalByteString getlogin_buffer {}; char* getlogin() { if (!getlogin_buffer.has_value()) { // ... 解析 /etc/passwd 中与当前有效 UID 匹配的条目 getlogin_buffer ByteString(passwd-pw_name); } return const_castchar*(getlogin_buffer-characters()); }这正是whoami与id -un行为一致的底层原因两者最终都归结于有效 UID → passwd 条目 → 用户名的同一条解析链路。同时/etc/passwd的只读权限普通用户无法修改保证了用户名查询结果的可靠性。常见问题与使用注意为什么whoami不接受--help之类的选项手册页的 Synopsis 中明确只允许裸调用这是刻意保持的最小化设计。若需要更丰富的身份信息请使用id(1)如id -un打印用户名、id -u打印 UID、id -g打印 GID。普通用户能查询到 root 吗不能。whoami只反映当前进程自身的有效身份它不会也不应该泄露其他用户的信息要改变身份需要借助su/setuid等提权途径。输出内容来自哪个文件用户名解析基于/etc/passwd这正是源码中unveil只放行该文件的原因。SerenityOS 默认的常规用户为anon超级用户为root。小结whoami虽然只有一行输出却是理解 SerenityOS 进程身份模型的最佳入口通过 手册页 掌握用法通过 whoami.cpp 学习标准工具骨架与 pledge/unveil 安全实践再通过 LibC 的getlogin()深入有效 UID → 用户名的解析实现三者串联起来便构成了一个完整、可验证的权限查询知识闭环。【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考