사용자가 루트가 아닌 경우 hidepid=2를 사용할 때 실행 권한만 있는 바이너리 프로세스가 여전히 "ps"에 숨겨져 있는 이유는 무엇입니까?

사용자가 루트가 아닌 경우 hidepid=2를 사용할 때 실행 권한만 있는 바이너리 프로세스가 여전히 "ps"에 숨겨져 있는 이유는 무엇입니까?

사용자가 자신의 프로세스만 볼 수 있도록 /proc를 hidepid=2로 마운트했습니다. 내가 사용하려는 특정 바이너리는 rwx--x--x 권한으로 제한되어 있으므로 소유자(루트)만 읽을 수 있지만 다른 사용자는 실행할 수 있습니다. 일반 사용자라면 문제없이 실행할 수 있지만 "ps"로 프로세스를 볼 수는 없습니다. 사용자가 읽을 수 있도록 바이너리의 권한이 변경되면 해당 프로세스가 다시 "ps"에 표시됩니다.

재현 가능한 예:

sudo mount -o remount,hidepid=2 /proc
sudo cp $(which yes) /tmp
sudo chmod 0711 /tmp/yes
/tmp/yes >/dev/null &
ps aux | grep yes # The process is hidden
sudo ps aux | grep yes # The process can be seen by root
kill %1
sudo chmod og+r /tmp/yes
/tmp/yes >/dev/null &
ps aux | grep yes # The process appears in the list

왜 이런 일이 발생합니까? 분명히 파일 권한과 관련이 있지만 그렇지 않아야 합니다. 프로세스가 사용자에게 속한 경우 바이너리가 제한되어 있어도 사용자는 이를 볼 수 있어야 합니다.

내 생각엔 /proc/PID의 "exe" 링크가 실행 바이너리를 가리키기 때문에 커널은 바이너리 자체를 제외한 해당 디렉토리에 대한 모든 액세스를 비활성화하는 것 같습니다. 그러나 이것이 사실인지 아니면 단지 다른 일이 일어나고 있는 결과인지 궁금합니다.

미리 감사드립니다!

답변1

대답은 (또는 적어도시작) 존재하다fs/proc/base.c(적어도 커널 3.12에서 4.2로 변경되지 않음)

742 static int proc_pid_permission(struct inode *inode, int mask)
743 {
744         struct pid_namespace *pid = inode->i_sb->s_fs_info;
745         struct task_struct *task;
746         bool has_perms;
747 
748         task = get_proc_task(inode);
749         if (!task)
750                 return -ESRCH;
751         has_perms = has_pid_permissions(pid, task, 1);
752         put_task_struct(task);
753 
754         if (!has_perms) {
755                 if (pid->hide_pid == 2) {
756                         /*
757                          * Let's make getdents(), stat(), and open()
758                          * consistent with each other.  If a process
759                          * may not stat() a file, it shouldn't be    seen
760                          * in procfs at all.
761                          */
762                         return -ENOENT;
763                 }
764 
765                 return -EPERM;
766         }
767         return generic_permission(inode, mask);
768 }

/proc/PID위의 코드는 특정 항목이 존재하는지 확인하는 시작점입니다. hide_pid2 로 설정 하면 -ENOENT필요한 권한이 없는 경우 이 값이 반환됩니다. 권한은 다음을 통해 확인됩니다.

has_pid_permissions()ptrace_may_access()__ptrace_may_access()

__ptrace_may_access()프로세스 생성 중에 결정된 대로 읽을 수 없는 실행 가능 이미지에서 프로세스가 생성되었기 때문에 프로세스가 "덤프 가능"하지 않기 때문에 액세스가 거부되었습니다.

setup_new_exec()would_dump()

1118 void would_dump(struct linux_binprm *bprm, struct file *file)
1119 {
1120         if (inode_permission(file_inode(file), MAY_READ) < 0)
1121                 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1122 }

관련 정보