本篇默认以Linux系统为例,除非特别说明。
一、进程和进程边界
1、进程和线程
进程:资源的分配单位。
线程:在CPU多核情况下,并发的执行序列,基本的调度单位。
2、手机操作系统的发展
Feature Phone时代的实时简单的单进程多任务非智能系统
Smart Phone时代的多进程多任务智能系统
3、进程的地址空间边界(虚拟内存)
32位操作系统决定了每个进程4G。开始的3G-4G映射的是同一块内核区。
进程的地址空间是有边界的,由于每个进程的0-3G的地址都被mapping到一个独立的物理内存区域,而且两个进程的虚拟内存绝对不会mapping到相同的物理地址。相互间不可见
4、进程边界的安全围栏:Crash的不可扩展性
5、进程边界的安全围栏:全局数据和服务的不可访问性
二、多用户和多用户边界
1、需求背景
资源缺乏、中央统一管理。
2、多用户边界:独立的工作目录
3、多用户边界:可操作/访问的资源
不同用户可操作/访问的资源时不一样的。(资源分类、权限管理)
4、多用户边界:可执行的操作
操作分类、权限管理
5、多用户的特性标识:UID和GID (后面还会有)
Name只是供看的.
Identifier才是系统层面的标识.
用户的行为是一系类进程的行为.
用户的特性标识其实是(演变为)进程的UID和GID.
三、进程和文件的UID和GID(一)重要!
1、文件资源的权限力度:UID/GID
文件是一类资源,在linux中甚至一切皆是文件。
文件资源对不同Target(用户)的不同操作权限的需求应运而生。
如何描述和区分不同Target?
通过ID——》即Linux的UID——》他是惟一的。
某些场景下,允许多个不同的Target/用户(而不是一个)具有一致的操作权限怎么办?
通过ID——》即Linux的GID——》多个用户可以属于一个GID,一个用户可以属于多个GIDs。
所以文件权限的管理力度区分为3类群体:属于特定UID的用户,属于特定GID的用户(们),其他用户。
一个跟存在:ROOT,其UID =0,永远满足 属于任何UID
2、文件的可操作权限
可读r、可写w、可执行x
3、进程的标识:PID,UID,GID,GIDs
PID:进程的Unique Identifier。唯一。每次Running的PID 可能相同,或者不同,由系统分配。
UID:进程的身份标识。每次运行,都默认相同,不同进程允许有相同的UID。
GID:进程的(组)身份标识。每次运行,默认相同。不同进程允许有相同的GID。同一进程允许属于多个GID。
GIDs:进程所属的全部GID。
四、进程和文件的UID和GID(二)重要!
1、Name和ID的映射
Android下:
android 第一个app user 从10000开始。(会省略10000)
2、Chmod和Chown命令介绍
文件R/W/X的系统内部采用3Bit表示,R为最高位比特,置位为0x04;W为中间比特,置位为0x02;X为最低比特,置位为0x01.
Shell中表示时,置位使用相应的R/W/X表示,未置位使用-。
操作文件面向群体的操作权限时,使用Chmod,可以直接使用数字,也可用助记符(a:all,u:owner user,g:group ,+:add one permission,-:remove onr permission)
demo:
Chown用于修改文件的UID和GID。
SHELL命令中通常采用Name方式修改,而不是ID方式。
一般格式chown newUID:newGID FIleName
3、UID/GID的衔接
Linux一切皆是文件。
文件基于UID/GID来划分它的面向群体,对他的面向群体定义不同的操作权限。
用户的行文映射为进程的运行。
进程的运行使用进程的UID/GID来标识自己的身份。
所以进程的UID/GID《====》文件的UID/GID 完美衔接。(解决进程能否访问文件的问题)
进程的UID/GID除了被授予可操作文件的范畴外,非文件范畴的需要进行权限控制的操作(如重启系统)继续通过进程的UID/GID身份来进行控制和授权。
比如对Reboot这个API,其入口处可以check calling的Process的UID,如果不是Root,则Reject。
五、进程的RealUID和EffectiveUID
1、身份的标识:Real UID
进程的UID只是泛称,其实有很多种不同的UID。
进程的Real UID是进程的身份标识,用来说明自己是谁。
仅仅说明自己是谁,但没有实权是不行的。
Linux中,进程能做什么不是由Real UID来决定的。
Real UID仅仅是身份,有身份无权利是无用的。
2、权利的标识:Effective UID
Effective UID是进程的权利的标识。标识了该进程的权利。
Linux中的进程授权(即 当前进程具有的操作权限)是靠Effective UID来识别的。
有权利技能做一切,Linux中具有特权的Effective UID的进程能为所欲为。
之前讲的文件、资源、以及特权API操作时对进程是否有权限的识别的UID,既是指Effective UID。
3、身份和权力的关系
一般情况下,身份和权利是一致的,即Real UID = Effective UID。
所以默认PS CMD输出的UID指的是 Effective UID。而没有输出Real UID。
我们也可以显示完整的Real UID和 Effective UID。
4、ROOT用户的特权
Effective UID = ROOT的进程具有皇权,它不受任何限制。
可以为自己正身:如果自己的身份(Real UID)不是Root,他可以将自己的身份名正言顺的改成ROOT(调用SetXUID)从而使得身份和权利均是ROOT。
他也可以自降身份:将自己的Real UID 和 Effective UID均设置(降低,也是调用SetXUID)为非特权普通的 Real UID , Effective UID。
5、UID的世袭
UID世袭遵循:身份世袭而权利不世袭。
子进程的Real UID = Effective UID = 父进程的Real UID。
这使得临时夺权且尚未正身(普通Real UID二特权 Effective UID)的进程的子嗣不能继承其特权而仅能继承其的正身(Real UID)
六、文件的setUID标识
1、平明身份,皇族特权的需求背景
demo:Linux的passwd是一个可执行程序(CMD)用于修改用户的密码,他需要操作多用户的账号文件(该文件高度安全,仅有ROOT用户可以读写),但是普通用户也应可以修改自己的密码。所以Passwd进程虽然是贫民身份(普通用户启动它),但却有皇族的权利。身份和权力不一致。
2、如何解决
临时提升特权(Effective UID)而维持身份不变(Real UID)使得其利用特权行驶职责时可避免世袭的安全问题。
3、Linux的文件setUID标识
文件的Owner UID 为特权用户 比如ROOT。
文件面向Owner UID的群体的操作权限增加额外的setUID标志。
Linux系统保证,任何用户(进程)执行该可执行文件(会Fork一个新的进程来加载该可执行文件running)时,该可执行文件所在的子进程的RealUID仍然继续继承其父进程的Real UID,但是其Effective UID不在等于其父的Real UID而是被提升到该可执行文件的Owner 的UID。
4、Chmod设置setUID 的方式
和基本的RWX设置类似,有助记符和直接数字设置。使用数字时,采用4位数字,第一位标志setUID。
5、setUID的安全问题
sUID的进程的EUID提升了。
sUID的进程的RUID默认没有提升。
在sUID进程的RUID没有正身(也设置为ROOT)之前,其子民的RUID/EUID只是平民。(目前还是安全的)
要依据实际情境,有限制的决定是否要在sUID进程中为自己正身,需要明确知道其后果是,其任何子民的RUID/EUID将均变为贵族(ROOT)。
两个例子:passwd(未正身),Android中的su(正身)
6、有RealGID,EffectiveGID,setGID吗?
有(自学)
七、Capability
1、UID怎么了
权限的颗粒度太粗。
容易引起权限过剩。
权利溢出/过剩引起安全问题。
2、Capability:细粒度的权限控制
我们需要细粒度的权限。
除了皇帝,也需要不同的地方官
Linux引入Capability:每个Capability系统内以以为Bit代表,OS内部使用64bit存储
3、进程的Capability
Permitted Capability Sets
当前进程的权利的围栏,最大的权利范围,是Effective Capability Sets的超集。
Effective Capability Sets
当前进程的实际使用的权利集,该集内的Capability必须从属于Permitted Capability Sets。该集合与Effective UID类似,是实际的权利标识。
Inheritable Capability Sets
子进程唯一可以直接继承的Capability Sets。在Capability 模式下,只有子进程的Inheritable Capability Sets = 父进程的Inheritable Capability Sets。其他皆是NO。
4、文件的Capability
Permitted Capability Sets
该可执行文件可以为其进程带来的Permitted Capability Sets。
Effective Capability Sets
仅1bit,Enable or Disable,标识该可执行文件running所在的进程的Permitted Capability Sets是否自动全部Assign到其Effective Capability Sets。通常用于与传统的Root-setUID可执行文件向下兼容。
Inheritable Capability Sets
与进程的Inheritable Capability Sets一起作用(位与)以决定新的进程的Permitted Capability Sets。
5、Capability BoundSet
Capability BoundSet是进程的属性。
是进程自己为自己设定的安全围栏(Capability Sets),限制可执行文件的Permitted Capability Sets仅有局部能转化为进程的Permitted Capability Sets。
Capability BoundSet能够被子进程继承。
Init进程默认Capability BoundSet为全1。
6、Spawn进程的Capability
p:进程
p' :子进程
F:可执行文件
P'(permitted)=(P(Inheritable)&(F(Inheritable))|(F(permitted)&Capability BoundSet)
P'(permitted)=F(effective)?P'(permitted):0
P'(Inheritable) = P(Inheritable)
7、Capability与UID的兼容
新技术必须向下(前)兼容,要保证旧的实体(应用)工作正常。
八、高级特性
1、被ROOT了怎么办
DAC和MAC的策略模式区别
DAC(Discretionary Access Control)自主访问控制:传统的Unix/Linux安全管理模型;主题对它所属的对象和运行的程序拥有全部的控制权。
MAC(Mandatory Access Control强制访问控制):SELinux基于的安全策略;管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。采用最小特权方式,默认下应用程序和用户没有任何权限。