IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

为什么会有 setuid?为什么不是别的机制?

林健的BLOG 2012-07-19 12:36:40 累计浏览 2,602 次
本机暂存

      来我们组面试过的同学,如果在简历中写了“熟悉 Unix/Linux”之类的话,那么很可能被问到类似这样的问题:“为什么会有 setuid?为什么不是别的机制?”。前不久和徐老师讨论设计原则问题时又聊到了这个 setuid。应徐老师建议,写下这篇命题作文,说说我的理解。

       首先从 setuid 的应用场景谈起。很多教科书和网络文章讲 setuid 时都会拿 passwd 命令举例(据说老一辈人更喜欢举 mailbox 的例子,异曲同工)。我们抛开对已知实现方式的理解,假设需要重新设计,看看这个场景有哪些需求和解决方案。需求方面,一种典型理解是:要求用户 a 可以使用程序 φ 受控地操作用户 b 的文件 θ。所谓受控,是指满足一个操作约束集合 S。除此之外,用户 a 对用户 b 的其他文件没有任何特权。事实上这就是一个访问控制问题,前人已经总结了若干解决模型。完备的角色访问控制(RBAC)或许能够涵盖全部需求,只要系统或管理员为特定的业务提供特定的角色并严格控制会话;即便使用自主访问控制(DAC),只要实现得足够细粒度,也可以尽力满足上述需求,只是安全性保证略差。但以文件为主要客体抽象的 Unix 偏偏选择了一种粗粒度的 DAC——ugorwx。为什么要做出这种选择?这很可能与 Unix 的“简单(K.I.S.S.)”设计哲学密切相关。相比其他模型,ugorwx 对系统和应用作出最少的必要假设,在提供最基本安全性的同时保证了较小的存储和决策开销。单纯使用 ugorwx 模型已经能够涵盖大多数正常业务操作(与系统管理或实用工具操作相对)的访问控制共性需求。

       然而 ugorwx 不能满足 passwd 和 mailbox 那样的需求,因为它对 θ 的控制粒度太粗,允许 b 使用 φ 操作 θ,就意味着必须允许所有用户使用任意程序操作 θ,那么篡改他人密码、偷看他人邮件岂不易如反掌?于是,必须要有一种额外机制为 ugorwx 的简单性承担责任。现在假设要我们来设计这个额外机制,可以怎么干呢?万全之道可能是做一套基于规则的访问控制系统,在特定条件触发时执行——这显然不够简单。还可以给每个用户或文件挂一个访问控制列表(ACL),声明特权,但其实主体之间的特殊关系可以通过 group 约束,ACL 这种特殊化不但不够简单,还可能违背了 ugorwx 的设计初衷。那么,只能把目光集中到那个特殊的程序 φ 上。可以对它做一些手脚吗?其一,φ 只是一小类需要特殊处理的例外程序,程序本身是可以精心设计的,也就是说 φ 已经自包含了 S 和 θ 属性,无须对 S 和 θ 做专门处理。其二,既然 ugorwx 的设计将主体关系特殊性交由 group 处理,那么就有理由忽略各个 others 成员的特殊性,即忽略 a。其三,b 对 θ 的 owner 关系是 ugorwx 中已经存在的,φ 运行时访问 θ,可以获知这个信息。基于上述事实,一种最小开销的额外机制设计也就水到渠成:通过一个特殊的标志位标识特殊的程序 φ,并在进程中区分“真实 UID”与“有效 UID”的概念——这基本就是 setuid 了。论功能,setuid 的确不够完备,但上述分析说明这并不是大问题,至少已经可以应对 passwd 和 mailbox 场景了。

       事实上,Unix 设计哲学对各个属性的取舍早已得到总结。Richard Gabriel 的经典名篇 The Rise of “Worse is Better”中将其归纳为“新泽西方法”,即:简单性是系统设计的第一要素,实现的简单比接口的简单更重要;任何值得注意的方面都要求正确性,但为了简单性,正确性可以轻微让步;设计不能过于不一致,但为了简单性,一致性可以有所牺牲;完备性应该覆盖实践中许多重要的情况,但只要简单性受到危害,完备性必须作出牺牲。对照来看,ugorwx 是一种接口和实现都很简单的设计;ugorwx 与 setuid 提供的安全级别(正确性)有限,但对通用操作系统来说已经足够;setuid 以牺牲接口一致性为代价确保了 ugorwx 机制在多数情况下的简单性,同时本身的实现也保持了尽量简单;setuid 不具有 RBAC 那样的完备性,但已经能够应对系统管理或实用工具的等常见的重要场景。

       最后,我们向历史求证一下 setuid 的来源。Wikipedia 给出的答案并不令人惊讶,setuid 的创造者正是 Dennis Ritchie 大神,当时的一篇专利(US4135240 - Protection of data file contents)记录了他的设计思想。在这篇如同学术论文的专利中,Ritchie 确实把简单性作为了 setuid 的主要出发点和创新点。专利风格诚恳,不但给出了 setuid 的设计方案和应用示例,同时也承认了它在功能上的不足。根据 Wikipedia 上给出的引文,AT&T 出于“不值得收取许可费用”的考虑,将该专利释放到了公有领域,任由开发者使用,这也使得 setuid 在多种衍生系统中发扬光大,流传至今。

       当然,对于这种开放性问题,每个人都可能有自己的答案,本文观点也只是作者的个人理解。不过如果你下次面试时遇到了诸如“为什么会有 ioctl”之类的问题,不妨从设计哲学角度考虑一下。

同分类推荐文章

  1. Windows 95 defenses against installers that overwrite a file with an older version (2026-03-25 07:04:03)
  2. 提权实录:通过命名管道劫持可写服务 (2026-03-16 00:00:00)
  3. 黑盒视角下的 WebView 漏洞面探索 (2025-12-26 00:00:00)

查看更多 安全 文章 →

建议继续学习

  1. 如何学好C语言 (累计阅读 6,383)
  2. CI框架里用的验证码 (累计阅读 5,760)
  3. linux后端服务程序之信号处理 (累计阅读 4,745)
  4. 为flash建立socket安全策略文件服务器 (累计阅读 4,722)
  5. 在Mac上删除Google的流氓软件 (累计阅读 4,528)
  6. linux下如何自动提升权限 (累计阅读 4,501)
  7. SAE云服务安全沙箱绕过5(强制修改class私有权限) (累计阅读 4,465)
  8. 验证码的几个常见漏洞 (累计阅读 4,302)
  9. 一个 VLA (可变长度数组)的实现 (累计阅读 4,315)
  10. Android安全–检测是否为Android模拟器 (累计阅读 4,020)