0%

File Access Right/Mode/Permissions (文件权限)

Access Right

1
2
3
4
5
6
7
8
9
$ touch tree
$ stat tree
File: `tree'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd18h/64792d Inode: 38100480 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 501/ xxx) Gid: ( 501/ xxx)
Access: 2018-11-08 23:35:55.749317495 +0800
Modify: 2018-11-08 23:35:55.749317495 +0800
Change: 2018-11-08 23:35:55.749317495 +0800

字段 Access 代表文件权限

1
Access: (0664/-rw-rw-r--)

其中:

  • 左起第一个位置,代表文件类型
  • 从左向右,三个位置为一组,分别是user, group, other权限
  • 每个小组细分,从左向右,依次是读、写、执行权限

    1
    2
    3
    4
    5
    6
    r 读权限
    w 写权限
    # 下面三个权限标志全部在第三个位置显示
    x 执行权限
    S set-user/group-ID
    s 执行权限 + set-user/group-ID
  • 若对应权限存在则显示代表字母,否则用 ‘-‘ 表示

若一个进程想操作文件,必须有对应权限才可以。

具体权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
S_ISUID  set-user-ID on execution
S_ISGID set-group-ID on execution
S_ISVTX saved-text (sticky bit) # S_ISVTX 权限用到的不多,暂且不介绍 **

# 所属用户有读,写,执行权限
S_IRUSR user-read # 4
S_IWUSR user-write # 2
S_IXUSR user-execute # 1

# 所属组用户有读,写,执行权限
S_IRGRP group-read # 4
S_IWGRP group-write # 2
S_IXGRP group-execute # 1

# 其他用户有读,写,执行权限
S_IROTH other-read # 4
S_IWOTH other-write # 2
S_IXOTH other-execute # 1

rw- 即 4 + 2 = 6

特殊介绍一下 S_ISUID

(S_ISGID 与 S_ISUID,基本一致,只要把对应的“用户”概念,替换为“组”)

When we execute a program file, the effective user ID of the process is usually the real user ID, and the effective group ID is usually the real group ID. But the capability exists to set a special flag in the file’s mode word (st_mode) that says “when this file is executed, set the effective user ID of the process to be the owner of the file (st_uid).” Similarly, another bit can be set in the file’s mode word that causes the effective group ID to be the group owner of the file (st_gid). These two bits in the file’s mode word are called the set-user-ID bit and the set-group-ID bit.

一个进程(执行的程序)都有一个 effectvie user ID,effectvie user ID 标志当前进程的权限。当这个进程准备去操作一个文件时通常是用 effectvie user ID 的权限去尝试。但是文件提供了一个属性,当这种属性被打开,当进程执行该文件时,进程的 effectvie user ID 将被修改为该文件的 owner user ID,这样就用 owner user ID 的权限继续执行了。这个属性就是 S_ISUID。

最常见的,在Linux系统中 passwd 命令就开启了 S_ISUID 属性,这样非root用户可以修改自己的秘密,并将密码更新到 /etc/passwd 文件

1
2
$ ll /usr/bin/passwd
-rwsr-xr-x 1 root root 30768 Nov 24 2015 /usr/bin/passwd

Shell 中 umask 命令

mask 有隐藏,伪装的意思。umask 表示当进程创建文件时,有哪些权限需要被隐藏,即不能将哪些权限赋予新创建的文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ umask
0002 # 隐藏 other 的写权限
$ strace touch tree # 打印命令执行中调用系统api,部分省略,可看到默认创建的 tree 属性为 0666
execve("/bin/touch", ["touch", "tree"], [/* 28 vars */]) = 0
brk(0) = 0x1b7f000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fec727c4000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
#...
open("tree", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
dup2(3, 0) = 0
close(3) = 0
utimensat(0, NULL, NULL, 0) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
$ ll tree
-rw-rw-r-- 1 xxx xxx 0 Nov 8 23:35 tree

tree的最终权限为: 0666 & (~0002) = 0664 即 rw-rw-r–。
所以, umask与创建文件命令提供的权限共同决定一个新建文件的权限,最终权限为:

1
mode & (~umask)

Reference & Thanks

  • 《UNIX高级环境编程》