/PROC/[PID]各目录项的UID、GID是怎么来的

/PROC/[PID]各目录项的UID、GID是怎么来的

文章目录

  • /PROC/[PID]各目录项的UID、GID是怎么来的
    • 第一层:伪文件系统
      • inode_operation
      • .getattr
      • .lookup
    • 第二层:进程的dumpable属性
      • 物理上对应哪个字段
      • 这个字段什么时候更新

最近遇到一个好玩的现象: /proc/[pid] 下各目录有的跟随父目录UID,而有些则是ROOT。这个行为在不同操作系统上表现不一致。

在这里插入图片描述

经过一系列研究,发现 /proc/[pid] 目录及其各目录项在满足如下条件时跟随相应进程,否则采用默认值 ROOT

  • 对于任意情况/proc/sys/fs/suid_dumpable 设置为 1。设置后重启进程方生效。
  • 对于加载可执行文件的情况:当前进程具有读取该镜像的权限,且其 UID 与 SUID 一致、GID 与 SGUID 一致
  • 对于父进程 FORK 的情况: 若父进程满足上述条件,则子进程继承父进程,同样满足

本文后续部分基于 Linux v5.17 内核,展开上述结论的推导过程。注意,

第一层:伪文件系统

从根文件系统到 /proc 这一层暂且不表。

聚焦目标,首先看 /proc/[pid] 及其各目录项 /proc/[pid]/pident 的 UID 和 GID 如何设置。

inode_operation

根据经验,首先找到 ‘/proc’ 这一目录的 inode_operation proc_root_inode_operations (链接),及 ‘/proc/[pid]’ 的 inode_operation proc_tgid_base_inode_operations(链接)。二者有关设置 UID 的流程上没有差异。

.getattr

可以看到,stat 时用于生成 struct kstat.getattr 方法本质只是对 generic_fillattr 的简单封装,本质上讲,还是要看 inode 中的相关字段。

所以我们将目光转向 .lookup 方法。

.lookup

众所周知,VFS inode_operations 的 ‘.lookup’ 用于生成 struct inode 并将之与 VFS 层生成的 struct dentry 绑定。顺着 lookup 追踪,很快就发现了设置 UID 及 GID 的位置 task_dump_owner

现摘录其中四段核心逻辑:

// 第一段
if (unlikely(task->flags & PF_KTHREAD)) {*ruid = GLOBAL_ROOT_UID;*rgid = GLOBAL_ROOT_GID;return;
}
...// 第二段
cred = __task_cred(task);
uid = cred->euid;
gid = cred->egid;
...// 第三段
...// 第四段
*ruid = uid;
*rgid = gid;
  • 第一段说明:对于内核进程,inode->i_uid 赋予 ROOT,这个没什么好说的
  • 第二、四段说明:在没有意外的情况下,/proc/[内核线程] 赋予 euid

第三段就是上面提到的意外了,下面我们特地展开分析:

if (mode != (S_IFDIR|S_IRUGO|S_IXUGO)) {struct mm_struct *mm;task_lock(task);mm = task->mm;if (mm) {// 第三段if (get_dumpable(mm) != SUID_DUMP_USER) {struct user_namespace *user_ns = mm->user_ns;uid = make_kuid(user_ns, 0);if (!uid_valid(uid))uid = GLOBAL_ROOT_UID;gid = make_kgid(user_ns, 0);if (!gid_valid(gid))gid = GLOBAL_ROOT_GID;}} else {uid = GLOBAL_ROOT_UID;gid = GLOBAL_ROOT_GID;}task_unlock(task);
}

显然,同时满足如下条件被设置为 ROOT

  • 该目录项不得是目录:不论如何,进程至少拥有遍历自己 PROC 目录及其子目录的权利。但至于文件内容能不能 DUMP 就另说了。
  • 该进程不得是核态进程
  • 该进程必须为 dumpable :展开起来有些篇幅,我们单独用一个章节展开。

第二层:进程的dumpable属性

物理上对应哪个字段

// https://elixir.bootlin.com/linux/v5.17/source/include/linux/sched/coredump.h#L29
static inline int __get_dumpable(unsigned long mm_flags)
{return mm_flags & MMF_DUMPABLE_MASK;
}static inline int get_dumpable(struct mm_struct *mm)
{return __get_dumpable(mm->flags);
}

这个字段什么时候更新

  1. 加载可执行镜像时设置(链接)
    if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP ||!(uid_eq(current_euid(), current_uid()) &&gid_eq(current_egid(), current_gid())))set_dumpable(current->mm, suid_dumpable);
    elseset_dumpable(current->mm, SUID_DUMP_USER);
    
    当镜像文件不可读,或 EUID 和 UID 不匹配时,直接使用全局变量 suid_dumpable。该全局变量可通过 /proc/sys/fs/suid_dumpable 维护。
  2. 刷新进程 CRED 结构体时
    根据第一条,不难得到本条
  3. 通过 prctl 系统调用强行刷新(链接)
    比如安卓的 Zygote 中的如下代码片段(链接):
    if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {ALOGE("prctl(PR_SET_DUMPABLE) failed");
    }
    
  4. 当进程通过 FORK 产生时(链接)
    if (current->mm) {mm->flags = current->mm->flags & MMF_INIT_MASK;mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK;
    } else {mm->flags = default_dump_filter;mm->def_flags = 0;
    }
    
    对于初始进程,不可 DUMP;对于子进程,继承父进程 dumpable 属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1620669.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

lab8 lock

PreRead 第六章3.5节:物理内存分配器8.1-8.3 文章目录 PreReadMemory allocatortaskshints思路 Buffer cachetaskhints思路实现 这次的lab,本质上都是通过将锁的粒度减小来获得性能的提升 第一个task,可以简单地按cpu划分,因为本…

GiD 前处理 实例

目录 Blog Links一、前言二、创建 1/8 半球体2.1 创建圆弧及圆球面2.2 创建半球面等分点2.3 连接等分线2.4 生成 1/8 半球体 三、创建整个球体四、划分网格五、尾声六、参考文献 Blog Links DalNur | 博客总目录 GiD 实用教程 GiD 前处理 实例 GiD 自定义 简介 GiD 后处理 …

Linux 建立用户和修改用户UID,GID

预设用户名为tom,UID222,GID222 首先我们来创建一个用户,创建用户命令: useradd tom(useradd 用户名) 创建好用户名后,再来创建用户的密码,于是接着创建密码,创建密码命…

Android中UID、GID和PID的讲解

一、概述 在实际的开发中经常会碰到各种ID,这是由于在计算机的发展过程中,需要对程序执行的每一步做标记,通过这些标记的关联便于系统的统一管理。像PID、UID、GID、和EUID等,其实对于这些ID不需要刻意记忆,只需要了解…

Linux中的UID、GID和SID

一、 UID和GID vi /etc/passwd查看用户配置情况 GID 是组ID (Group Identify),表示组的身份唯一标识 UID 是用户ID (User Identify),表示用户身份唯一标识 用户分类 centos6 超级用户 UID0 root 普通用户 UID500起 oldboy 虚拟用户 UID1-499 存在满足…

GiD初步使用

GiD软件具有全面的几何建模、网格划分、CAD数据导入、后处理结果显示等功能。GiD采用类似于CAD的操作模式,用户在使用GiD创建复杂模型问题时,会感受到前所未有的方便和轻松。它易于操作、方便灵活、直观便捷。 1. 下载与安装 到官方网站下载适合电脑配…

用户账号-用户标识符:UID与GID

虽然我们登录Linux主机的时候,输入的是我们的账号,但是其实Linux主机并不会直接认识你的“账号名称”的,它仅认识ID。ID与账号的对应关系在/etc/passwd当中。 每个登录的用户至少都会取得两个ID,一个是用户ID(UserID&…

Android 安全机制(1)uid 、 gid 与 pid

1、概述 Android 安全机制来源于Linux,并且以Linux权限管理为基础,要了解Android的安全机制,需要从linux中的安全机制了解开始,而用户的权限管理又是linux安全机制的最基本的一个组成. Android的创新之处是在linux用户权限管理的…

UID、EUID、GID和EGID

UID、EUID、GID和EGID Linux中id真是太多了进程有pid,然后用户还有UID这种,真是有点绕。 在Linux当中一个进程(程序)拥有四个ID:真实用户UID、有效用户EUID、真实组GID和有效组EGID。 这里以真实用户UID和有效用户EUID为例&…

用户和用户组-UID和GID

用户和用户组-UID和GID Linux用户和用户组用户UID用户组GID/etc/passwd 文件结构/etc/shadow 文件结构 Linux用户和用户组 Linux采用一个32位的整数记录和区分不同的用户。这个区分不同用户的数字被称为User ID,简称UID。Linux系统中用户分为3类,即普通…

linux uid gid 作用,Linux uid和gid

Linux uid和gid教程 我们在登陆 Linux 系统时,虽然输入的是自己的用户名和密码,但其实 Linux 并不认识你的用户名称,它只认识用户名对应的 ID 号(也就是一串数字)。Linux 系统将所有用户的名称与 ID 的对应关系都存储在 /etc/passwd 文件中。…

GiD 自定义 简介

目录 Blog Links一、前言二、GiD的程序架构三、问题类型系统四、主配置文件/.spd文件4.1 单位制4.2 截面属性4.3 局部轴 五、Tcl文件5.1 GiD程序调用GiD-Tcl5.2 执行程序的命名空间 六、参考文献 Blog Links DalNur | 博客总目录 GiD 实用教程 GiD 前处理 实例 GiD 自定义 简…

GiD 实用教程

目录 Blog Links一、前言二、用户界面2.1 界面组成2.2 快捷键2.3 模式切换2.4 图层功能2.5 删除功能2.6 视图切换2.7 渲染视图 三、帮助与实例3.1 帮助文档3.2 官方实例 四、GiD Basics五、几何模型5.1 点的定义5.2 线的创建5.3 面的创建5.4 体的创建 六、网格划分6.1 布设种子…

python 双向链表

双向链表基本介绍 双向链表增删改查操作思路分析 双向链表增删改查操作代码实现 """ 双向链表的增删改查 """# 英雄类 class HeroNode:next None # 指向下一个节点,默认为空pre None # 指向前一个节点,默认为空def …

小马哥的CSS驿站

目录 第一章 CSS概述 1.1语法 1.2注释 1.3CSS的创建 第二章 CSS选择器 1.id选择器 2.class选择器 3.标签选择器 4.子代选择器 5.后代选择器 6.相邻兄弟选择器 7.后续兄弟选择器 8.交集选择器 9.并集选择器 第三章 CSS样式 1.文本与文字样式 (1&…

35 岁财务自由的小马哥,我想跟他学学!

如果说 Java 工程师,有什么一定要“死磕”拿下的东西,那一定是 Spring 无疑了。 众所周知,Spring 无论在 Java 生态系统,还是在就业市场,是绝对的王者。Spring AOP 作为 Spring 框架的核心内容之一,其重要性…

计算机网络(速率、宽带、吞吐量、时延、发送时延)

速率: 最重要的一个性能指标。 指的是数据的传送速率,也称为数据率 (data rate) 或比特率 (bit rate)。 单位:bit/s,或 kbit/s、Mbit/s、 Gbit/s 等。 例如 4 1010 bit/s 的数据率就记为 40 Gbit/s。 速率往往是指额定速率或…

什么盒模型

一、盒模型 1.什么是盒模型 在我们HTML页面中,每一个元素都可以被看作一个盒子,而这个盒子由:内容区(content)、填充区(padding)、边框区(border)、外边界区&#xff0…

1.1 编辑楼层标高

在任意视图内批量编辑楼层。点击 按钮,弹出楼层管理器界面,可以对模型中已有的楼层高度进行修改、批量修改楼层名称。在创建楼层时,可以设定起始楼层序号,后续楼层将自动排序,当前文件中的新建楼层在“确定”完成前允许自由删除操…

2.3 轴生墙

按照已创建的弧形/ 直线轴生成墙。点击 按钮,弹出轴线生墙对话框,如图所示:在基本墙中选择需要添加的墙类型,在顶高和底高中选择楼层,并可以勾选是否按楼层切分墙。可在墙上定位线中选择墙的中心或者外边缘等为定位线…