![사용자가 루트가 아닌 경우 hidepid=2를 사용할 때 실행 권한만 있는 바이너리 프로세스가 여전히 "ps"에 숨겨져 있는 이유는 무엇입니까?](https://linux55.com/image/73715/%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B0%80%20%EB%A3%A8%ED%8A%B8%EA%B0%80%20%EC%95%84%EB%8B%8C%20%EA%B2%BD%EC%9A%B0%20hidepid%3D2%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%A0%20%EB%95%8C%20%EC%8B%A4%ED%96%89%20%EA%B6%8C%ED%95%9C%EB%A7%8C%20%EC%9E%88%EB%8A%94%20%EB%B0%94%EC%9D%B4%EB%84%88%EB%A6%AC%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EA%B0%80%20%EC%97%AC%EC%A0%84%ED%9E%88%20%22ps%22%EC%97%90%20%EC%88%A8%EA%B2%A8%EC%A0%B8%20%EC%9E%88%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
사용자가 자신의 프로세스만 볼 수 있도록 /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_pid
2 로 설정 하면 -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 }