Linux进程权限的研究——real user id, effective user id, saved set-user-id

每个Linux进程都包含这些属性,这些属性共同决定了该进程访问文件的权限 :

1. real user id

2. real group id

3. effective user id

4. effective group id

5. saved set-user-id

6. saved set-group-id

1,2 简称ruid、rgid ,由启动进程的用户决定,通常是当前登录用户(运行可执行文件的用户);

3,4 简称euid/egid ,一般在进程启动时,直接由1,2复制而来;或者是当进程对应的可执行文件的set-user-id/set-group-id(chmod u+s)标志位为true时,为该文件的所属用户/组,这组属性决定了进程访问文件的权限;

5,6 简称suid/sgid,从euid/egid复制。

下面这张图描述了进程启动时,这些属性是怎么赋值的:

扫描二维码关注公众号,回复: 1581952 查看本文章


1-2 : 由登录用户启动运行可执行文件,启动进程;

3: 设置进程的rid/rgid为当前登录用户的uid/gid;

4:设置进程的eid/egid,根据可执行文件的set-user-id/set-group-id属性(红色:0, 紫色:1),为1时,设为可执行文件的uid/gid,否则从rid/rgid拷贝。

/* sample1.c, 打印本进程的ruid, euid, suid */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <pwd.h>
int main()
{
	struct passwd* ruser = NULL;
	struct passwd* euser = NULL;
	struct passwd* suser = NULL;
	uid_t uid, euid, suid;
	/* get uid euid suid */
	if(getresuid(&uid, &euid, &suid) != 0)
	{
		perror(0);
		return 1;
	}
	/* get name of id */
	ruser = getpwuid(uid);
	printf("real user: %s\n", ruser->pw_name);
	euser = getpwuid(euid);
	printf("effective user: %s\n", euser->pw_name);
	suser = getpwuid(suid);
	printf("saved set-user-id user: %s\n", suser->pw_name);
	return 0;
}

 编译生成a.out。 
 

执行ls -l a.out,查看可执行文件属性:


执行./a.out,  可以看到三个用户均为当前登录用户:


若执行sudo ./a.out, 则三个用户全为root用户


设置set-user-id位为1: 执行chmod u+s  a.out, 可以看到user的x属性变成了s:

 

执行sudo  ./a.out, rid为登录用户,euid/suid和a.out文件的uid一致,此时进程虽然用sudo启动,但读写文件时只具有普通用户(euid: xuwei)的权限: 


以上仅以user id为例, 对于相应的group id, 其原理是一样的。

本文提到“effective id”实际决定文件读写权限,“real id”和“saved id”有什么用呢?下节会介绍。

猜你喜欢

转载自blog.csdn.net/ybxuwei/article/details/23563423