用户、权限与访问控制
复习
- 共享内存与内存映射:把文件访问与共享页面统一起来
- 断电时写到一半怎么办:崩溃一致性与写入顺序
- 日志文件系统:先记下修改意图,再安全地更新真实结构
TL;DR
- 一台机器往往被多个用户共用,不能谁都能随便动别人的东西
- 操作系统给每个用户一个身份,用权限决定谁能读、谁能写、谁能执行
- 常见的权限模型:用户、组、以及读/写/执行三组位
- 内核在每次访问时检查,不满足就拒绝
正文
前面讲了进程如何隔离内存。可光隔离内存还不够:同一台机器上,Alice 的文件凭什么不让 Bob 改?设备凭什么不能人人随便用?这就要有一套访问控制。
身份:用户与组
访问控制的第一步,是知道“你是谁”。操作系统给每个使用者一个用户身份,还可以把若干用户归入一个组。
每个文件(以及其他资源)通常记录着它的所有者和所属组。这样一来,判断权限时就有了三方的概念:文件的主人、同组的伙伴、以及其他人。
权限:读、写、执行
对文件来说,最基本的三种操作是:
- 读(r):能不能看内容
- 写(w):能不能修改内容
- 执行(x):能不能把它当作程序运行
Unix 系的做法是把权限分成三组——所有者、组、其他人——每组各三个“允许/不允许”位:
文件权限: rwx r-x r-- (所有者可读写执行,组可读执行,其他人只可读)
检查发生在每次访问
权限不是摆设,每一次访问都要检查。当你打开一个文件时,内核会:
- 看你是谁、属于哪个组
- 看这个文件的权限里,对应你这一方(所有者 / 组 / 其他人)允许做什么
- 如果这次操作不在允许之列,就拒绝——通常返回一个“权限不足”的错误
访问请求 ──> 内核:你是谁?该文件允许你这么做吗?
├─ 允许 → 放行
└─ 拒绝 → 报错
因为检查在内核里、在真正的操作之前完成,用户程序绕不过去。
特权与“最小权限”
还有一类特殊的用户,拥有特权(比如系统管理员),可以越过普通权限做几乎任何事——安装软件、改配置、管理其他用户。特权是把双刃剑:方便,却也危险。
所以一条重要原则是最小权限:程序平时只拿它真正需要的那点权限,不做无关的敏感操作。这样,即使它出了错或被利用,能造成的破坏也有限。这条原则,后面讲安全时还会反复提到。
思考题
为什么权限检查必须由内核来做,而不能交给程序自己“自觉遵守”?如果只是“约定”而不强制,会发生什么?
小结
知识点
- 用户与组:访问控制中的身份
- 读、写、执行三种基本权限
- 权限按所有者、组、其他人分别设置
- 内核在每次访问前检查权限
- 最小权限原则
参考资料
- Wikipedia(zh):文件系统权限:file permissions
- Wikipedia(zh):访问控制:access control
思考题答案(仅供参考)
因为“自觉遵守”的前提是每个程序都诚实可靠,而现实中总有写错的、有恶意的。如果权限只是约定,一个坏程序完全可以无视约定,直接去读别人的文件、改系统数据,约定形同虚设。把检查放进内核、在特权态强制执行,程序就绕不过去:它根本接触不到被禁止的操作。安全机制必须强制,不能靠自觉——这也是内核态、用户态等一整套保护存在的理由。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪