• 进程中的权限是如何操作的


    任何一个进程都有父进程。所以,整个进程其实就是一棵进程树。而拥有同一父进程的所有进程都具有兄弟关系。

    1. struct task_struct __rcu *real_parent; /* real parent process */
    2. struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
    3. struct list_head children; /* list of my children */
    4. struct list_head sibling; /* linkage in my parent's children list */
    • parent 指向其父进程。当它终止时,必须向它的父进程发送信号。
    • children 表示链表的头部。链表中的所有元素都是它的子进程。
    • sibling 用于把当前进程插入到兄弟链表中。

    通常情况下,real_parent 和 parent 是一样的,但是也会有另外的情况存在。例如,bash 创建一个进程,那进程的 parent 和 real_parent 就都是 bash。如果在 bash 上使用 GDB 来 debug 一个进程,这个时候 GDB 是 parent,bash 是这个进程的 real_parent。

    real_cred 就是说明谁能操作我这个进程,而 cred 就是说明我这个进程能够操作谁。这里 cred 的定义如下:

    1. struct cred {
    2. ......
    3. kuid_t uid; /* real UID of the task */
    4. kgid_t gid; /* real GID of the task */
    5. kuid_t suid; /* saved UID of the task */
    6. kgid_t sgid; /* saved GID of the task */
    7. kuid_t euid; /* effective UID of the task */
    8. kgid_t egid; /* effective GID of the task */
    9. kuid_t fsuid; /* UID for VFS ops */
    10. kgid_t fsgid; /* GID for VFS ops */
    11. ......
    12. kernel_cap_t cap_inheritable; /* caps our children can inherit */
    13. kernel_cap_t cap_permitted; /* caps we're permitted */
    14. kernel_cap_t cap_effective; /* caps we can actually use */
    15. kernel_cap_t cap_bset; /* capability bounding set */
    16. kernel_cap_t cap_ambient; /* Ambient capability set */
    17. ......
    18. } __randomize_layout;

    从这里的定义可以看出,大部分是关于用户和用户所属的用户组信息。

    第一个是 uid 和 gid,注释是 real user/group id。一般情况下,谁启动的进程,就是谁的 ID。但是权限审核的时候,往往不比较这两个,也就是说不大起作用。

    第二个是 euid 和 egid,注释是 effective user/group id。一看这个名字,就知道这个是起“作用”的。当这个进程要操作消息队列、共享内存、信号量等对象的时候,其实就是在比较这个用户和组是否有权限。

    第三个是 fsuid 和 fsgid,也就是 filesystem user/group id。这个是对文件操作会审核的权限。

    一般说来,fsuid、euid,和 uid 是一样的,fsgid、egid,和 gid 也是一样的。因为谁启动的进程,就应该审核启动的用户到底有没有这个权限。

    capabilities,用位图表示权限,在 capability.h 可以找到定义的权限。

    1. #define CAP_CHOWN 0
    2. #define CAP_KILL 5
    3. #define CAP_NET_BIND_SERVICE 10
    4. #define CAP_NET_RAW 13
    5. #define CAP_SYS_MODULE 16
    6. #define CAP_SYS_RAWIO 17
    7. #define CAP_SYS_BOOT 22
    8. #define CAP_SYS_TIME 25
    9. #define CAP_AUDIT_READ 37
    10. #define CAP_LAST_CAP CAP_AUDIT_READ

    对于普通用户运行的进程,当有这个权限的时候,就能做这些操作;没有的时候,就不能做,这样粒度要小很多。

    cap_permitted 表示进程能够使用的权限。但是真正起作用的是 cap_effective。cap_permitted 中可以包含 cap_effective 中没有的权限。一个进程可以在必要的时候,放弃自己的某些权限,这样更加安全。假设自己因为代码漏洞被攻破了,但是如果啥也干不了,就没办法进一步突破。

    cap_inheritable 表示当可执行文件的扩展属性设置了 inheritable 位时,调用 exec 执行该程序会继承调用者的 inheritable 集合,并将其加入到 permitted 集合。但在非 root 用户下执行 exec 时,通常不会保留 inheritable 集合,但是往往又是非 root 用户,才想保留权限,所以非常鸡肋。

    cap_bset,也就是 capability bounding set,是系统中所有进程允许保留的权限。如果这个集合中不存在某个权限,那么系统中的所有进程都没有这个权限。即使以超级用户权限执行的进程,也是一样的。

    cap_ambient 是比较新加入内核的,就是为了解决 cap_inheritable 鸡肋的状况,也就是,非 root 用户进程使用 exec 执行一个程序的时候,如何保留权限的问题。当执行 exec 的时候,cap_ambient 会被添加到 cap_permitted 中,同时设置到 cap_effective 中。

    此文章为10月Day24学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。

  • 相关阅读:
    卷积神经网络的图像分类技术研究毕设目录
    Tensorflow笔记——卷积神经网络
    LoGoNet:基于局部到全局跨模态融合的精确 3D 目标检测
    Hash 表
    eclipse如何引入lombok插件
    项目资源管理从学会向上管理开始
    增量学习 Demo
    【区块链实战】什么是 P2P 网络,区块链和 P2P 网络有什么关系
    <二>强弱指针使用场景之 多线程访问共享对象问题
    如何选择现代存储产品?这份指南供你参考!
  • 原文地址:https://blog.csdn.net/key_3_feng/article/details/134022703