我们平常接触的文件权限是3个8进制数:分别表示,owner user、owner group、others的读、写、执行权限。比如
755
7是4+2+1,表示文件所有者,有读、写、执行权限。
5是4+1,表示文件所在组,有读和执行权限。
5是4+1,表示其它用户,有读和执行权限,没有写权限。
1 2 3 4 5 6 7 8 9 | $ stat test File: test Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 802h /2050d Inode: 5402445 Links: 1 Access: (0755 /-rwxr-xr-x ) Uid: ( 1000/ yuan) Gid: ( 1000/ yuan) Access: 2024-09-04 19:43:21.512587346 +0800 Modify: 2024-09-04 19:43:21.512587346 +0800 Change: 2024-09-05 09:26:05.115500819 +0800 Birth: - |
我们在ls -l或者stat看到的是:rwxr-xr-x,共9个字母,分别表示文件所有者,文件所在组,其它用户的读写执行权限。
如果是-,则表示没有对应的权限。
linux文件还有3位特殊的权限。setuid、setgid、sticky bits。也是用一个8进制数表示。和普通权限组合再一起就是4个八进制数。
比如4755。第一个4就是表示特殊权限,表示有setuid,没有setgid和sticky bits。
使用字母表示时,和执行权限使用一个位置。
setuid和user的执行权限共用一个位置。
setgid和group的执行权限共用一个位置。
sticky bits和其它用户的执行共用一个位置。
setuid和setgid和执行权限组合的时候,有3个字母:x、s、S。
sticky bits和执行权限组合的时候,有3个字母,x、t、T。
s表示具有执行权限和setuid(setgid)权限。
S表示没有执行权限,具有setuid (setgid)权限。
t/T类似。
比如4755是:rwsr-xr-x。
755变成4755,可以使用
$ chmod u+s test
把用户的s加上就可以了。
现在来看这3个特殊权限的用途
如果一个可执行文件设置了setuid权限,那么当一个用户执行这个可执行文件时,运行进程的有效用户(effective user)就是文件的所有者而不是调用者。
这样,可以让一个用户以其它用户执行程序。特别的可以让一个普通用户以root用户执行程序。
像sudo、passwd这些程序,它的文件owner是root,它们设置了setuid权限。因此一个普通用户执行的时候,是以root用户权限执行的。
一个属于root的可执行文件,如果它设置了setuid,那么任何用户都将以root权限运行它。这可能是一个巨大的安全隐患。但是也提供了一种方法,来支持sudo、普通用户修改自己的密码等需要提权的功能。
我们把id程序,拷贝一份到本地,加上setuid权限,以普通用户运行看看:
$ cp /usr/bin/id .
$ sudo chown root:root id
$ sudo chmod u+s id
$ ./id
uid=1000(yuan) gid=1000(yuan) euid=0(root) groups=1000(yuan),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare)
可以看到euid变成了root。获得了root权限。但是uid还是调用者。
setuid对目录没有影响。
和setuid类似。运行程序的effective group变成可执行文件的组,而不是调用者的组。
和setuid不同的是,setgid对目录也有影响,如果一个目录设置了setgid,那么这个目录下创建的文件,其组是父目录的组,而不是创建者所在的组。
$ mkdir 123
$ sudo chmod g+s 123
$ sudo touch newa 123/newb
$ ls newa 123/newb -l
-rw-r--r-- 1 root yuan 0 Sep 5 10:35 123/newb
-rw-r--r-- 1 root root 0 Sep 5 10:35 newa
创建一个123目录,设置setgid。然后以root用户在123下面创建新文件。
可以看到新文件的group是父目录的组,而不是root。
外面的没有setgid的目录下,创建的新文件,group是root。
特别有用的是:
Created subdirectories also inherit the setgid bit.
新创建的目录,也继承setgid位。这就是说,一个目录设置了setgid位,那么这个目录下的子子孙孙都可以保持和这个目录一个组。
sticky bits对文件没有影响,设置在目录上,表示目录下的子文件,只有文件的所有者可以修改它。
这常用在/tmp目录上。/tmp目录所有人都可以读写。设置了sticky bits,表示各个读写者,只能修改自己的东西。
1 2 3 4 5 6 7 8 9 | $ stat /tmp File: /tmp Size: 12288 Blocks: 24 IO Block: 4096 directory Device: 802h /2050d Inode: 2752513 Links: 20 Access: (1777 /drwxrwxrwt ) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2024-09-04 19:17:24.704717315 +0800 Modify: 2024-09-05 09:24:09.695171895 +0800 Change: 2024-09-05 09:24:09.695171895 +0800 Birth: - |
参考
https://linuxconfig.org/how-to-use-special-permissions-the-setuid-setgid-and-sticky-bits