Linux内核进程管理子系统有什么第四十一回 —— 进程主结构详解(37)
接前一篇文章:Linux内核进程管理子系统有什么第四十回 —— 进程主结构详解(36)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
setuid系统调用及示例-CSDN博客
特此致谢!
进程管理核心结构 —— task_struct
8. 进程权限相关成员
进程权限相关成员包括以下几个:
/* Process credentials: *//* Tracer's credentials at attach: */const struct cred __rcu *ptracer_cred;/* Objective and real subjective task credentials (COW): */const struct cred __rcu *real_cred;/* Effective (overridable) subjective task credentials (COW): */const struct cred __rcu *cred;
这几个字段的描述如下:
上一回继续对于struct cred进行解析,本回仍然继续。为了便于理解和回顾,再次贴出struct cred的定义,在include/linux/cred.h中,如下:
/** The security context of a task** The parts of the context break down into two categories:** (1) The objective context of a task. These parts are used when some other* task is attempting to affect this one.** (2) The subjective context. These details are used when the task is acting* upon another object, be that a file, a task, a key or whatever.** Note that some members of this structure belong to both categories - the* LSM security pointer for instance.** A task has two security pointers. task->real_cred points to the objective* context that defines that task's actual details. The objective part of this* context is used whenever that task is acted upon.** task->cred points to the subjective context that defines the details of how* that task is going to act upon another object. This may be overridden* temporarily to point to another security context, but normally points to the* same context as task->real_cred.*/
struct cred {atomic_t usage;
#ifdef CONFIG_DEBUG_CREDENTIALSatomic_t subscribers; /* number of processes subscribed */void *put_addr;unsigned magic;
#define CRED_MAGIC 0x43736564
#define CRED_MAGIC_DEAD 0x44656144
#endifkuid_t uid; /* real UID of the task */kgid_t gid; /* real GID of the task */kuid_t suid; /* saved UID of the task */kgid_t sgid; /* saved GID of the task */kuid_t euid; /* effective UID of the task */kgid_t egid; /* effective GID of the task */kuid_t fsuid; /* UID for VFS ops */kgid_t fsgid; /* GID for VFS ops */unsigned securebits; /* SUID-less security management */kernel_cap_t cap_inheritable; /* caps our children can inherit */kernel_cap_t cap_permitted; /* caps we're permitted */kernel_cap_t cap_effective; /* caps we can actually use */kernel_cap_t cap_bset; /* capability bounding set */kernel_cap_t cap_ambient; /* Ambient capability set */
#ifdef CONFIG_KEYSunsigned char jit_keyring; /* default keyring to attach requested* keys to */struct key *session_keyring; /* keyring inherited over fork */struct key *process_keyring; /* keyring private to this process */struct key *thread_keyring; /* keyring private to this thread */struct key *request_key_auth; /* assumed request_key authority */
#endif
#ifdef CONFIG_SECURITYvoid *security; /* LSM security */
#endifstruct user_struct *user; /* real user ID subscription */struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */struct ucounts *ucounts;struct group_info *group_info; /* supplementary groups for euid/fsgid *//* RCU deletion */union {int non_rcu; /* Can we skip RCU deletion? */struct rcu_head rcu; /* RCU deletion hook */};
} __randomize_layout;
上一回讲解了struct cred中的3组字段:
前文书讲了以上3组字段,实际上要看struct cred的定义可以发现,3组字段中间还有1组字段没有提及,就是:
- 第4组 —— kuid_t suid和kgid_t sgid
suid与sgid的注释分别是saved UID/GID of the task。
在Linux中,一个进程可以随时通过setuid设置用户ID(User ID)。如上一回所讲的场景:用户想保存程序运行中的数据,就通过chmod u+s命令,给这个应用程序设置set-user-id。那么,之前应用程序的所有者李四的ID需要保存在一个地方,就是保存在这个suid和sgid里边。这样就能够很方便地使用setuid系统调用,通过设置uid或suid来改变权限。
这里要对于setuid系统调用进行知识补强。
知识补强 —— setuid系统调用
在Linux系统中,每一个进程都运行在一个特定的用户(User)上下文中。这个用户上下文决定了进程拥有哪些权限,如能否读、写、执行某个文件,能否绑定到特权端口(端口号小于1024的端口)等。
每个进程通常有三类相关的用户ID(User ID):
- 真实用户ID(Real User ID —— RUID)
登录系统时分配给用户的ID。它标识了“你是谁”。
这就对应的是struct cred中的uid成员:
kuid_t uid; /* real UID of the task */
- 有效用户ID(Effective User ID —— EUID)
内核用来进行权限检查时使用的ID。它决定了“你能做什么”。这是最重要的一个。
这就对应的是struct cred中的euid成员:
kuid_t euid; /* effective UID of the task */
- 保存的设置用户ID(Saved Set-User-ID —— SUID)
用于在有效用户ID和真实用户ID之间来回切换的一个“备份”ID。
这就对应的是struct cred中的suid成员:
kuid_t suid; /* saved UID of the task */
setuid(Set User ID)系统调用的主要作用是设置调用进程的有效用户ID(EUID)。根据调用者的权限和当前的ID状态,(可能)同时修改保存的设置用户ID(SUID)。
简而言之,setuid系统调用可以让程序“以某个用户的身份”去执行操作,从而获得或限制与该用户相关的权限。
下一回继续对于setuid系统调用进行知识补强。