prctl(PR_SET_DUMPABLE, 0); 之后符号链接变得不可读

prctl(PR_SET_DUMPABLE, 0); 之后符号链接变得不可读

我是kcheckpass在下面调试的Archlinux。 (因为我登录失败kcheckpass

不知何故,我相信这个特定问题不在kcheckpass.

int
main(int argc, char **argv)
{
#ifdef HAVE_PAM
  const char    *caller = KSCREENSAVER_PAM_SERVICE;
#endif
  const char    *method = "classic";
  const char    *username = 0;
#ifdef ACCEPT_ENV
  char      *p;
#endif
  struct passwd *pw;
  int       c, nfd, lfd;
  uid_t     uid;
  time_t    nexttime;
  AuthReturn    ret;
  struct flock lk;
  char fname[64], fcont[64];

  // disable ptrace on kcheckpass
#if HAVE_PR_SET_DUMPABLE
  prctl(PR_SET_DUMPABLE, 0);

在执行第一行之前:prctl(PR_SET_DUMPABLE, 0);

ls /proc/$(pidof kcheckpass)/exe  -al
lrwxrwxrwx 1 wuyihao wuyihao 0 Jan 16 16:16 /proc/31661/exe -> /cker/src/build/kcheckpass/kcheckpass

执行后:

ls /proc/$(pidof kcheckpass)/exe  -al
ls: cannot read symbolic link '/proc/31661/exe': Permission denied

/proc/31661/root与和相同/proc/31661/cwd

我没有看到coredump和读取权限之间有任何联系/proc/$PID/exe

更新

最小的例子重现了这个问题:

#include <sys/prctl.h>
#include <stdio.h>
int main(){
    prctl(PR_SET_DUMPABLE, 0);
    return 0;
}

更新2 kcheckpass最小的例子test是:

-rwsr-xr-x 1 root root

答案1

当您删除可转储属性时,其他进程将无法读取一堆/proc/<pid>/文件和链接,甚至由用户拥有。

联机prctl帮助页内容如下:

不可转储的进程不能通过附加 跟踪(2)PTRACE_ATTACH;看跟踪(2)了解更多详情。

如果某个进程不可转储,则该进程/proc/[pid]目录中文件的所有权会受到影响,如过程(5)

联机proc帮助页内容如下:

/proc/[pid]

每个/proc/[pid]子目录包含下面描述的伪文件和目录。这些文件通常由进程的有效用户和有效组 ID 拥有。但是,作为一项安全措施,如果进程的“可转储”属性设置为 1 以外的值,则所有权将设为 root:root。

最后,联机ptrace帮助页内容如下:

ptrace 访问模式检查

内核用户空间 API 的各个部分(不仅仅是ptrace() 操作)需要所谓的“ptrace 访问模式”检查,其结果决定是否允许操作(或者,在某些情况下,导致“读取”操作返回经过清理的数据)。

(...)

ptrace 访问模式检查所采用的算法确定是否允许调用进程对目标进程执行相应的操作。 (在打开文件的情况下/proc/[pid] ,“调用进程”是打开文件的进程,具有相应PID的进程是“目标进程”。)算法如下:

(...)

  1. 如果目标进程“可转储”属性的值不是 1 (...),并且调用者 CAP_SYS_PTRACE在目标进程的用户命名空间中不具备该功能,则拒绝访问。

相关内容