4、权限管理基础:用户与组的概念、权限位模型、特权与非特权模式

好,我们进入第四章。这一章讲的是权限管理的基础,说白了就是回答一个问题:谁,能对什么,做什么

我在做QNX系统安全审计的时候,发现很多问题其实不是漏洞多高级,而是最基础的权限模型没搞对。你想想看,一个嵌入式设备,如果连用户和组的概念都模糊,那后面的安全策略就是空中楼阁。

4.1 用户与组:谁在操作?

QNX是一个多用户操作系统,虽然很多嵌入式场景下只有一个root用户跑着,但千万别养成这个习惯。我见过一个项目,所有进程都用root跑,结果一个缓冲区溢出直接让攻击者拿到了整个系统的控制权——嗯,教训很深刻。

在QNX中,每个进程都有一个用户ID(UID)组ID(GID)。这两个ID决定了进程能访问哪些资源。

  • UID 0:超级用户(root),拥有至高无上的权限。说白了,它想删什么就删什么,想读什么就读什么。
  • UID 1-99:系统保留用户,用于运行系统服务。我个人习惯把关键服务(比如网络栈、存储管理)放在这些ID下,避免和普通应用混在一起。
  • UID 100+:普通用户,权限受限。你想想看,一个跑在普通用户下的进程,就算被攻破了,攻击者也拿不到系统核心数据。

组的概念类似,它是一组用户的集合。比如你可以创建一个sensor_group,只有这个组的进程才能访问某个温度传感器设备文件。

核心原则:最小权限

每个进程只分配它完成任务所需的最小权限。不要图省事全给root。

4.2 权限位模型:rwx 与 数字模式

QNX的权限位模型和POSIX标准一致,就是经典的读(r)、写(w)、执行(x)三组权限,分别对应文件所有者(owner)、同组用户(group)、其他用户(others)

举个例子,一个可执行文件/usr/bin/sensor_daemon,权限位可能是:

-rwxr-x---  1 root sensor_group  12345 Jan 1 12:00 /usr/bin/sensor_daemon

这表示:

  • 所有者(root)可以读、写、执行
  • 同组用户(sensor_group)可以读、执行,但不能写
  • 其他用户没有任何权限

数字模式更简洁:rwxr-x--- 对应 750。计算方法很简单:

权限二进制数字
r1004
w0102
x0011
rwx1117
r-x1015
---0000

所以 750 就是:所有者7(rwx),同组5(r-x),其他0(---)。

我的习惯: 在QNX中,我几乎不用777。哪怕是一个临时调试脚本,用完也要立刻改回755750。曾经有一次,一个同事把日志目录设成777,结果被一个低权限进程把日志文件全删了——排查了一整天。

4.3 特权模式 vs 非特权模式

QNX的微内核架构下,特权模式和非特权模式的区别非常关键。说白了,就是你能不能直接操作硬件

  • 特权模式(内核态):运行在QNX微内核中的代码(比如进程管理器、内存管理器)拥有完全权限。它们可以直接操作MMU、中断控制器、时钟等硬件资源。
  • 非特权模式(用户态):普通进程运行在这里。它们不能直接访问硬件,必须通过系统调用(比如MsgSend()ChannelCreate())向内核请求服务。

为什么会这样设计?你想想看,如果每个进程都能直接操作硬件,那一个进程写错了内存地址,整个系统就崩了。QNX把关键操作收归内核,用户进程只能通过消息传递来请求——这就是它高可靠性的根基。

注意: 在QNX中,即使你是root用户,你的进程默认也是运行在非特权模式下的。root只是让你有权限调用某些系统调用,但不会让你直接操作物理内存。这一点和Linux不同,QNX更严格。

我曾经遇到过一个案例:一个硬件驱动团队把驱动逻辑全写在了用户态,结果频繁出现优先级反转和死锁。后来我们把核心时序逻辑移到了内核态的一个资源管理器中,问题就解决了。嗯,这就是特权模式的价值——它保证了关键操作的原子性和实时性。

4.4 实战:如何配置一个安全的进程权限

假设我们要启动一个网络监控进程net_monitor,它需要读取网络接口状态,但不需要修改网络配置。我会这样配置:

  1. 创建一个专用用户netmon和组netgroup
  2. net_monitor可执行文件的所有者设为netmon:netgroup
  3. 权限位设为750(所有者rwx,同组r-x,其他无)
  4. 在启动脚本中,使用su netmon -c "/usr/bin/net_monitor"启动

这样,即使net_monitor被攻破,攻击者也拿不到root权限,更动不了系统核心文件。

避坑指南: 我曾经见过一个项目,把setuid位设在了ping命令上。结果攻击者利用ping的一个漏洞,直接以root权限执行了任意代码。所以,慎用setuid/setgid,能用能力(capability)解决的问题,就别用setuid。

4.5 小结

这一章我们讲了三个核心概念:

  • 用户与组:区分谁在操作,实现权限隔离
  • 权限位模型:rwx和数字模式,控制文件/设备访问
  • 特权与非特权模式:内核态 vs 用户态,保护系统核心

记住一句话:权限不是越多越好,而是越精确越好。下一章我们会深入QNX特有的能力(capability)模型,那才是QNX权限管理的精髓所在。