【文件管理】访问权限与文件安全性

来源:互联网 发布:列宁为什么杀沙皇 知乎 编辑:程序博客网 时间:2024/04/29 22:25

Unix类的OS的安全性总的来说是不差于相关系统的,Unix文件系统的访问权限是一种二维结构;


(1)就对一个用户来说,访问权限被分成了读,写,和执行三种方式;就同一种访问方式来说,则可能因为访问者的身份属于文件主,文件主的同组人以及其他用户,而分别决定允许与否,因此一共有9中组合;一个用户有一个唯一的用户号uid,而每一个用户组则有唯一的组号gid,这些记录在/etc/password中;每一个inode记录着文件主的uid,gid,以及文件访问的模式;task_struct中相应的设置了uid和gid;每当用户通过登录进系统并创立第一个shell进程时,就从/etc/password中根据用户名查的其uid和gid,并将其设置到该进程的tasklet的uid和gid;内核在执行用户进程访问文件的请求时要对比进程(用户)的uid,gid以及文件的访问模式,已决定该进程是否有对此文件所要求的访问权限;uid为0的是超级用户,对任何文件都具有与文件主相同的权限;用户名和用户号是多对一的关系,因此一个用户号(权限)可授予多个用户;

(2)为了防止超级用户为所欲为,可通过进程的用户号和组号来改变或限制其访问权限,由此出现了真实uid,真实gid,以及有效uid,有效gid;于是tasklet中有了euid,egid,并有对应的系统调用,如setuid();再改变有效uid时,往往需要把原来的uid保存起来,以便以后恢复,于是task_struct就有了suid和sgid;在NFS的网络环境下,又增设了fsuid和fsgid,它们通常与euid,egid相同;只有特权用户以及具有特权用户权限的进程才可以设置set_uid以及set_gid;通过su我们是可以获得特权用户的权限的;

(3)除文件主外,所有的用户都只能对/etc/password读不能写;但是某些程序是需要写权限的,比如修改自己的密码,unix的做法就是加标记(S_ISUID,以及SISGID),一旦执行完毕后,还回到以前的权限;但是这种标记其实也是一个漏洞;对于sticky是将一些频繁的程序运行完毕后可继续是其映像保存到内存中;但是如今linux采用了虚存管理,所以这个标志已经没有意义了;文件模式是以16位无符号整数表示的,现在用去可9位以及(S_ISUID,以及SISGID,sticky)3位,接下来的4位用来表示一种文件类型;这16位的文件模式存储在每一个文件的索引节点中,这就是每一个进程是否有权对某个文件进行某种访问基础;

(4)对于权限的检查,一般如果文件系统,比如ext2有自己的权限检查,就应该优先执行对应的权限检查(文件,目录,链接都有对应的operations的permission,其实ext2未提供);否则就执行通用的vfs_permission();

(5)在vfs_permission()中,IS_READONLY表示节点所在的文件系统,即磁盘设备,是按只读方式安装的 ,对于常规文件,目录,符号链接都是不能写的;但是对于FIFO文件,设备文件,那就未必是不可写的,因为对这些文件的写访问实际上不会或不一定写到该设备所在的磁盘上的;在较新的linux系统中,除访问权限又给每一个文件加上了一些属性,如不可更改,这些属性也像标志位一样存储在文件的索引节点,但是不会像访问权限那样区分文件主,文件主的同组用户以及其他用户,而且这些属性,即使是特权用户也无法将它更改;如一个文件被设置成了不可更改,那么即使是超级用户通过chmod()把访问文件的模式设置成可写也是无济于事的;如EXT2_APPEND_FL表示对文件的写访问权限只能添加在文件的末尾,而不能改变文件中已有的文件内容;对于用户中append只是用户的一厢情愿,而这个是强制添加的;S_IMMUTABLE为1,就剥夺了所有用户的对这个文件的写权限,而它与文件设置的访问权限是无关的;EXT2_NODUMP_FL,意图是使可执行文件在运行访问内存出错时,不要生成dump文件(就是内存崩溃时,将出错的内存映像装载到磁盘文件以便调试的);屏蔽这个也是为了从安全性考虑的;因此在task_struct中有一个dumpable标志,可以设置;以及系统调用prctl()以便完全杜绝其产生dump文件的可能性,其实就是设置EXT2_NODUMP_FL

(6)vfs_permission()中,mode是取自inode中文件访问模式,mask是要访问的权限;但与当前进程的fsuid在网络系统时有可能与euid不同的,在此还要判断进程所属的组号(一个进程可能属于多个组)是否与文件主的组号是否相符,相符mode>>3;否则mode>>6(如果是文件主的话);如果当前进程确实不属于文件主的同组人,就是其他组的人,不需要移位的;此时mode的低三位与S_IRWXO(为7),一般不符就失败可,但是如果进程得到了授权,允许其CAP_DAC_OVERRIDE,就可以凌驾于文件系统的访问权限机制DAC上面了,但是不影响前面的只读文件以及不可获得写权限的;另一种授权是CAP_DAC_READ_SEARCH,可以让该进程读任何文件,并且可以搜索粉盒目录节点;搜索目录的权限是执行而不是读,因此是MAY_EXEC;

(7)用户进程在一定条件下可以通过系统调用来设置其用户号,如setuid(),setfuid(),seteuid()等;下面介绍setuid()是设置用户号的调用;

(8)在setuid()中,进程的fsuid和euid肯定会被设置成新的uid,但是如果是euid为0的进程都具有CAP_SETUID权限,它的suid也要被设置成新的uid;每当改变euid时,都要将dumpable清0,这样进程访问出错就不会产生dump文件了;如果CAP_SETUID权限,就连用户的真实uid也要改写,由于进程按照用户号通过user_struct挂入杂凑表uidhash,现在用户号换了,因此要分配新的user_struct,释放就的user_struct;

(9)对于文件的授权是独立于文件系统的访问权限德尔,并且凌驾于其上的机制,目前有29中授权,于是一个32位的无符号整数就够用了;当进程改变其uid时,要通过cap_emulate_setxuid()检查并可能改变其授权的情况,除非编译内核时,有开关忽略了对进程的授权机制,在cap_emulate_setxuid()中,如果有效用户号从0编程非0,则cap_effective将会被清零,但是cap_permitted未变,以后这个进程euid恢复成0的时候,就可以用cap_permitted来恢复cap_effective了;但是如果uid,suid,euid全都改变了,那两个就要都被零了,但是可以通过keep_capablilities来避免清零,,通过prctl来设置的;

(10)最初的授权是通过prepare_binprm()来准备一些授权的情况,可通过capset()来减少授权的;在compute_creds中,将linux_binprm和当前进程已有的一些权限进行整合,其中1号进程的授权已固定的;

0 0
原创粉丝点击