ILD

linux special file permissions: setuid, setgid, sticky bits
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2024-9-5 站点:Inside Linux Development

Normal file permissions

    我们平常接触的文件权限是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个字母,分别表示文件所有者,文件所在组,其它用户的读写执行权限。

如果是-,则表示没有对应的权限。


Special file permissions

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

    如果一个可执行文件设置了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对目录没有影响。


setgid

和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

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


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.