当我具有正确的功能时,无法打开/ proc / self / oom_score_adj

weixin_38063608 2019-09-12 10:28:16
我试图为一个过程设置OOM杀手分数调整,受到oom_adjust_setup in OpenSSH’s port_linux.c的启发.为此,我打开/ proc / self / oom_score_adj,读取旧值,并写入一个新值.显然,我的进程需要是root或具有CAP_SYS_RESOURCE能力才能做到这一点. 我得到了一个我无法解释的结果.当我的进程没有该功能时,我能够打开该文件并读取和写入值,尽管我写的值没有生效(足够公平): $./a.out CAP_SYS_RESOURCE: not effective, not permitted, not inheritable oom_score_adj value: 0 wrote 5 bytes oom_score_adj value: 0 但是当我的进程确实具有该功能时,我甚至无法打开该文件:它与EACCES失败: $sudo setcap CAP_SYS_RESOURCE+eip a.out $./a.out CAP_SYS_RESOURCE: effective, permitted, not inheritable failed to open /proc/self/oom_score_adj: Permission denied 为什么这样做?我错过了什么? 一些进一步的谷歌搜索引导我到this lkml post by Azat Khuzhin on 20 Oct 2013.显然CAP_SYS_RESOURCE允许您更改任何进程的oom_score_adj,但你自己.要更改自己的分数调整,您需要将其与CAP_DAC_OVERRIDE结合使用 – 即禁用所有文件的访问控制. (如果我想要的话,我会把这个程序设为setuid root.) 所以我的问题是,如果没有CAP_DAC_OVERRIDE,我怎样才能做到这一点? 我正在运行Ubuntu xenial 16.04.4,内核版本4.13.0-45-generic.我的问题类似但与this question不同:这是关于写入时的错误,当没有能力时. 我的示例程序: #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/capability.h> void read_value(FILE *fp) { int value; rewind(fp); if (fscanf(fp, "%d", &value) != 1) { fprintf(stderr, "read failed: %s\n", ferror(fp) ? strerror(errno) : "cannot parse"); } else { fprintf(stderr, "oom_score_adj value: %d\n", value); } } void write_value(FILE *fp) { int result; rewind(fp); result = fprintf(fp, "-1000"); if (result < 0) { fprintf(stderr, "write failed: %s\n", strerror(errno)); } else { fprintf(stderr, "wrote %d bytes\n", result); } } int main() { FILE *fp; struct __user_cap_header_struct h; struct __user_cap_data_struct d; h.version = _LINUX_CAPABILITY_VERSION_3; h.pid = 0; if (0 != capget(&h, &d)) { fprintf(stderr, "capget failed: %s\n", strerror(errno)); } else { fprintf(stderr, "CAP_SYS_RESOURCE: %s, %s, %s\n", d.effective & (1 << CAP_SYS_RESOURCE) ? "effective" : "not effective", d.permitted & (1 << CAP_SYS_RESOURCE) ? "permitted" : "not permitted", d.inheritable & (1 << CAP_SYS_RESOURCE) ? "inheritable" : "not inheritable"); } fp = fopen("/proc/self/oom_score_adj", "r+"); if (!fp) { fprintf(stderr, "failed to open /proc/self/oom_score_adj: %s\n", strerror(errno)); return 1; } else { read_value(fp); write_value(fp); read_value(fp); fclose(fp); } return 0; }
...全文
667 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38067871 2019-09-12
  • 打赏
  • 举报
回复
这个非常有趣破解,花了我一段时间. 第一个真正的提示是对另一个问题的回答:https://unix.stackexchange.com/questions/364568/how-to-read-the-proc-pid-fd-directory-of-a-process-which-has-a-linux-capabil – 只是想给予信任. 它不能正常工作的原因 如果进程具有任何功能,则获得“权限被拒绝”的真正原因是/ proc / self /下的文件由root拥有 – 它与CAP_SYS_RESOURCE或oom_ *文件无关.您可以通过调用stat并使用不同的功能来验证这一点.引用男人5 proc: /proc/[pid] There is a numerical subdirectory for each running process; the subdirectory is named by the process ID. Each /proc/[pid] subdirectory contains the pseudo-files and directories described below. These files are normally owned by the effective user and effective group ID of the process. However, as a security measure, the ownership is made root:root if the process’s “dumpable” attribute is set to a value other than 1. This attribute may change for the following reasons: The attribute was explicitly set via the prctl(2) PR_SET_DUMPABLE operation. The attribute was reset to the value in the file /proc/sys/fs/suid_dumpable (described below), for the reasons described in prctl(2). Resetting the “dumpable” attribute to 1 reverts the ownership of the /proc/[pid]/* files to the process’s real UID and real GID. 这已经暗示了解决方案,但首先让我们深入挖掘一下,看看那个人是怎么回事: PR_SET_DUMPABLE (since Linux 2.3.20) Set the state of the “dumpable” flag, which determines whether core dumps are produced for the calling process upon delivery of a signal whose default behavior is to produce a core dump. In kernels up to and including 2.6.12, arg2 must be either 0 (SUID_DUMP_DISABLE, process is not dumpable) or 1 (SUID_DUMP_USER, process is dumpable). Between kernels 2.6.13 and 2.6.17, the value 2 was also permitted, which caused any binary which normally would not be dumped to be dumped readable by root only; for security reasons, this feature has been removed. (See also the description of /proc/sys/fs/suid_dumpable in proc(5).) Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances: The process’s effective user or group ID is changed. The process’s filesystem user or group ID is changed (see credentials(7)). The process executes (execve(2)) a set-user-ID or set-group-ID program, resulting in a change of either the effective user ID or the effective group ID. The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process. Processes that are not dumpable can not be attached via ptrace(2) PTRACE_ATTACH; see ptrace(2) for further details. If a process is not dumpable, the ownership of files in the process’s /proc/[pid] directory is affected as described in proc(5). 现在很清楚:我们的进程具有用于启动它的shell没有的功能,因此dumpable属性设置为false,因此/ proc / self /下的文件由root而不是当前用户拥有. 如何使它工作 修复程序就像在尝试打开文件之前重新设置dumpable属性一样简单.在打开文件之前粘贴以下内容或类似内容: prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); 希望有所帮助;)

435

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧