我们首先来说一下传统的Linux基于uid,gid的权限管理机制:
1、用户的uid gid gids:
Ubuntu操作系统当前登陆的用户是jltxgcy,那么该用户的uid为jltxgcy,gid也是jltxgcy,那么gids怎么查看呢?
答案是使用命令:cat /etc/group | grep jltxgcy。如下图:
用户的gids的名字为adm,dialout,cdrom,plugdev,lpadmin,admin,sambashare。此本分请参考linux用户组、/etc/group文件及账户相关操作命令。
2、进程的uid gid gids:
shell进程uid,gid,gids都来源于用户,也就是说,该用户的进程的uid,gid,gids就是用户的uid,gid,gids;
另外很重要的一点是进程中其实没有uid,有的只有realUid和effectiveUid。
对于一般的进程来说realUid等于effectiveUid。在进程中真正有作用的effectiveUid。realUid象征着身份,effectiveUid象征着权力。
子进程realUid和effectiveUid都等于父进程的readUid。在shell中执行命令,其实就是fork出了shell进程的子进程。
文件操作时对进程是否有权限的识别的UID,即是指effectiveUid。ps命令输出的UID是effectiveUid。
3、文件的拥有者,群组:
对于/bin/cat来说文件拥有者 为root,群组 为root。说明只有effectiveUid为root的进程才可以对文件进行rwx,gids包含root的进程可以对文件进行rx,其他的进程只可以对文件x。
下面举个例子把刚才讲的内容串联起来。
当前用户为jltxgcy,所以当前进程(shell进程的子进程)的realUid等于effectiveUid都为jltxgcy。
然后执行命令cat test,如上面两个图,对于cat来说当前进程effectiveUid为jltxgcy对这个文件来说是可执行的,然后再看test,对于当前进程effectiveUid为jltxgcy来说是可读的,所以我们能够通过这个命令看到test里面的内容,而不会出现Permission Deny。
我们接下来要分享的是setUid。首先我们把touch命令改成具有setUid权限的命令,如下图:
然后使用touch命令来建立test1文件,我们看看有什么不同,如下图:
不同之处是,test的user是jltxgcy,而test1的user是root。
这是因为:当effectiveUid为jltxgcy的进程在执行touch时,由于touch命令的user有了setUid的权限,所以这个进程的effectiveUid被设置为了root,具有了“皇权”,但是realUid仍为jltxgcy。
由于子进程realUid和effectiveUid都等于父进程的readUid,所以它的子进程的realUid和effectiveUid都等于jltxgcy,未正身。
与之不同的su命令,su命令的user也具有setUid权限,su这个进程把自身的effectiveUid提升为root后,把realUid也提升为root。这样它的子进程就是名正言顺的root了,它的子进程的readUid和effectiveUid都为root了。
capability是比传统的rwx权限管理更为细粒度的权限管理,比如当前进程在执行setUid提升自己的effectiveUid时,就会检查effective capabilty sets是否允许setUid。
我们讲了这么多在Linux下的权限管理,那么在Android下的权限管理是怎么样的呢?
用户:在Android中用户的概念已经被淡化,通常使用的是root用户和shell用户。
进程:shell用户的进程effectiveUid为2000。为什么?
使用busybox的命令whoami,当前用户是的uid为2000,那么2000对应哪个用户呢?我们查看Android_filesystem_config.h的源码:
#define AID_SHELL 2000 /* adb and debug shell user */
所以当前用户是shell用户,并且shell进程的uid为2000。
当前进程,由于是shell进程的子进程,它的uid为2000,我们cc文件只有sdcard_r这个组才可以读,那么为什么我们的进程可以读这个文件呢?只有一种可能,那就是当前进程它的gids里面包含了sdcard_r。
为了验证我们的想法,请看下图:
12797是shell进程,我们看到Groups里面有gid为1015,1015就是对应sdcard_r。当前进程时shell进程的子进程,当然gids里面就包含了1015。
在Android中,shell是进程,命令执行时是shell的子进程,应用程序是进程。
这是应用程序的私有文件,这样的权限机制就阻止了其他进程访问,有效保障了安全。