linux文件权限

1,089 阅读8分钟

Linux下的文件权限分类:

  • Discretionary Access Control (DAC) 自主访问控制权限

    DAC又分为两类权限:

    • 经典的UNIX样式权限检查: 将当前进程UID和GID与正在访问的文件的UID和GID进行比较,以确定已设置的模式(读/写/执行)
    • POSIX Access Control Lists (ACL)
  • Mandatory Access Control (MAC) 基于策略的访问控制

    • selinux

本文聚焦于 经典的UNIX样式权限检查

核心知识图:

9207671-0a81b5ae28cc9d36..jpg

此文重点介绍,不同App进程,在/sdcard/Android/data 目录下的文件,group 为什么都是 ext_data_rw ,而不是自己进程的gid

sdcard 几种目录权限 全览:

xxxxxx:/ # cd sdcard/
kaiser:/sdcard # ll
total 81
drwx------ 2 u0_a229  u0_a229  3452 2021-04-26 05:26 Alarms
drwxrws--x 6 media_rw media_rw 3452 2021-05-19 16:44 Android
drwx------ 2 u0_a229  u0_a229  3452 2021-04-26 05:26 Audiobooks
drwx------ 4 u0_a229  u0_a229  3452 2021-05-13 15:59 DCIM
drwx------ 2 u0_a229  u0_a229  3452 2021-04-26 05:26 Documents
drwx------ 3 u0_a229  u0_a229  3452 2021-05-18 17:26 Download
drwx------ 5 u0_a229  u0_a229  3452 2021-05-06 21:12 MIUI
drwx------ 3 u0_a229  u0_a229  3452 2021-04-26 05:26 Movies
drwx------ 4 u0_a229  u0_a229  3452 2021-05-06 20:40 Music
drwx------ 2 u0_a229  u0_a229  3452 2021-04-26 05:26 Notifications
drwx------ 3 u0_a229  u0_a229  3452 2021-04-26 05:26 Pictures
drwx------ 5 u0_a229  u0_a229  3452 2021-05-20 10:35 Tencent

xxxxxx:/sdcard # cd Android/
xxxxxx:/sdcard/Android # ll
total 20
-rw-------  1 u0_a229  media_rw      33 2021-05-19 16:44 24ea15
-rw-------  1 u0_a229  media_rw      34 2021-05-19 16:44 aa3dcb
drwxrws--x 40 media_rw ext_data_rw 3452 2021-05-19 16:44 data
drwxrws--x  3 media_rw media_rw    3452 2021-04-26 05:28 media
drwxrws--x  2 media_rw ext_obb_rw  3452 2021-05-12 11:11 obb
drwx--S---  3 u0_a229  media_rw    3452 2021-05-18 18:17 obj
xxxxxx:/sdcard/Android # cd data/
xxxxxx:/sdcard/Android/data # ll
total 114
drwxrws--- 3 u0_a116    ext_data_rw 3452 2021-04-26 05:28 com.android.calendar
drwxrws--- 4 u0_a106    ext_data_rw 3452 2021-04-26 05:28 com.android.camera
drwxrws--- 3 u0_a168    ext_data_rw 3452 2021-05-07 17:00 com.android.fileexplorer
drwxrws--- 3 u0_a110    ext_data_rw 3452 2021-05-06 14:26 com.android.mms
drwx--S--- 3 u0_a71     ext_data_rw 3452 2021-04-26 05:26 com.android.providers.downloads
drwxrws--- 4 u0_a171    ext_data_rw 3452 2021-04-27 09:49 com.blackshark.bsaccount

libc中有这样一个函数:

// 头文件
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);

调用此函数会对 stat 结构体赋值:

struct stat  
{  
    dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/  
    ino_t       st_ino;     /* inode number -inode节点号*/
    mode_t      st_mode;    /* 文件的类型和存取的权限*/  
    nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/  
    uid_t       st_uid;     /* user ID of owner -user id*/  
    gid_t       st_gid;     /* group ID of owner - group id*/  
    dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/  
    off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/  
    blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/  
    blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/  
    time_t      st_atime;   /* time of last access -最近存取时间*/  
    time_t      st_mtime;   /* time of last modification -最近修改时间*/  
    time_t      st_ctime;   /* time of last status change - */  
};  

此结构体中有个 mode_t 类型的数据 st_mode,st_mode是个32位的整型变量:

其低16位的含义如图:

9207671-0a81b5ae28cc9d36..jpg

8进制下不同数值的含义

// 0170000 第一个0表示八进制。17转为十进制是15,是15位权限控制的最高4位。这四位的最大值0b1111,十进制为15,八进制表示法是017。
S_IFMT      0170000     文件类型的位遮罩  

S_IFSOCK    0140000     socket
S_IFLNK     0120000     符号链接(symbolic link)
S_IFREG     0100000     一般文件
S_IFBLK     0060000     区块装置(block device)
S_IFDIR     0040000     目录
S_IFCHR     0020000     字符装置(character device)
S_IFIFO     0010000     先进先出(fifo)
    
S_ISUID     0004000     文件的(set user-id on execution)位
S_ISGID     0002000     文件的(set group-id on execution)位
S_ISVTX     0001000     文件的sticky位
    
S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)
S_IRUSR     00400       文件所有者具可读取权限
S_IWUSR     00200       文件所有者具可写入权限
S_IXUSR     00100       文件所有者具可执行权限
    
S_IRWXG     00070       用户组的遮罩值(即所有权限值)
S_IRGRP     00040       用户组具可读取权限
S_IWGRP     00020       用户组具可写入权限
S_IXGRP     00010       用户组具可执行权限
    
S_IRWXO     00007       其他用户的遮罩值(即所有权限值)
S_IROTH     00004       其他用户具可读取权限
S_IWOTH     00002       其他用户具可写入权限
S_IXOTH     00001       其他用户具可执行权限
摘自《Linux C 函数库参考手册》

权限示例:0100724

// 看下 0 10 0 724 这个每个数值的含义:
/*
第一个0 表示8进制
10     表示文件类型为 一般文件,8进制下文件类型占据两个8位
第二个0 特殊权限UGT权限位
724    表示文件所有者具有全部权限,用户组具有写权限,其他用户具有读权限 
*/

文件权限与进程的关系:

进程所属的user、group、groups 需要有与文件有相应的权限才能访问文件:

xxxxxx: # ps -elZ | grep media.module
u:r:mediaprovider_app:s0:c229,c256,c512,c768 5 S 10229 4011 839 0 29 -10 64 1395645 do_epoll_wait ? 00:01:52 rs.media.module

xxxxxx: # ps -p 4011
USER            PID   PPID     VSZ    RSS WCHAN            ADDR S NAME
u0_a229        4011    839 5582580 144136 do_epoll_+          0 S com.android.providers.media.module

xxxxxx: # cat /proc/4011/status
Name:   rs.media.module
Umask:  0077
State:  S (sleeping)
Tgid:   4011
Ngid:   0
Pid:    4011
PPid:   839
TracerPid:      0
Uid:    10229   10229   10229   10229      # 进程所属的 user
Gid:    10229   10229   10229   10229      # 进程当前工作的 group
FDSize: 256
Groups: 1015 1023 1065 1077 1078 1079 3007 9997 20229 50229 99909997  # 进程所属其他 group 

xxxxxx:/ # id media_rw
uid=1023(media_rw) gid=1023(media_rw) groups=1023(media_rw) context=u:r:su:s0

# /sdcard/Android/media 的权限
drwxrws--x  3 media_rw media_rw    3452 2021-04-26 05:28 media

media_rw 用户进程,或者属于 media_rw 用户组的进程具有 /sdcard/Android/media 目录的读写权限
mediaprovider 进程不属于 media_rw 用户,当前工作的group为10229,也不属于media_rw,但是其Groups中有1023(media_rw)用户组,
因此 mediaprovider 进程具有 media 文件的读写访问权限

特殊权限位:

示例:

xxxxxx:~/work$ ls -l
total 157600
drwsrwSrwt 33 xxxxxx xxxxxx     4096 Feb 19 20:57 testfile
SUID

用SUID肯定满足一下几点: 1.SUID只对二进制文件有效 2.调用者对该文件有执行权 3.在执行过程中,调用者会暂时获得该文件的所有者权限 4.该权限只在程序执行的过程中有效

xxxxxx:~/work$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 47032 Jan 27  2016 /usr/bin/passwd

# 通过 passwd 进程修改密码,会修改 /etc/shadow 文件,但是普通用户没有权限
# 有了 SUID 位,调用者具有了 passwd所有者root的权限,因此可以写 /etc/shadow 文件

xxxxxx:~/work$ ls -l  /etc/shadow
-rw-r----- 1 root shadow 1770 May 12 15:30 /etc/shadow
SGID
  • 它作用于普通文件时,和SUID类似,在执行该文件时,用户将获得该文件所属组的权限。
  • 当SGID作用于目录时:
    • 前提,当用户对某一目录有写和执行权限时,该用户就可以在该目录下建立文件
    • 如果该目录用SGID修饰,则该用户在这个目录下建立的文件都是属于这个目录所属的组。
SBIT
  • 只能用来修饰一个目录。
  • 当某一个目录拥有SBIT权限时,则任何一个能够在这个目录下建立文件的用户,该用户在这个目录下所建立的文件,
  • 只有该用户自己root可以删除,其他用户均不可以。

解释/sdcard/Android/data 目录:

  • 手机在开机的时候会在 /sdcard/Android 默认创建 data 和 obb 目录
    • 这两个目录的权限都是 drwxrws--x media_rw ext_data_rw
    • 因为group位带有s权限,所以任何进程在这俩目录下创建的文件group都是 ext_data_rw

附:Android文件权限检查图:

qkimagesjisyjisy201911jisy20191134-1-l.jpg

其他 ACL 权限

/sdcard/Android/data /sdcard/Android/obb 这两个目录在Android上有 ACL权限 相关的代码,但是代码有没有运行,还不确定。