I'm using hidepid=2 to mount /proc, so users can't see any but their own processes. A particular binary I want to use has been restricted to rwx--x--x permissions, so only its owner (root) can read it but other users can execute it. A normal user can run it without problems, but can't see the process with "ps". If the binary has its permissions changed so the user can read it, then the process appears in "ps" again.
A reproducible example:
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
Why is this happening? It obviously has some relationship to the file permissions, but it shouldn't have: if the process belongs to a user, the user should be able to see it even if the binary is restricted.
My guess is that, as the link "exe" inside /proc/PID points to the binary being executed, the kernel is forbidding all access the the directory in addition to the binary itself. But I'd like to know if this is true or just a consequence of some other thing going on.
Thanks in advance!
The answer is (or at least starts) in fs/proc/base.c
(unchanged from kernel 3.12 to 4.2 at least)
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 }
The code above is the starting point for determining if a specific /proc/PID
entry can been seen to exist or not. When hide_pid
is set to 2 it returns -ENOENT
if you don't have the required permission. Permissions are checked via:
has_pid_permissions()
→ ptrace_may_access()
→ __ptrace_may_access()
__ptrace_may_access()
denies access because the process is not "dumpable" as it was created from an unreadable executable image, as determined during process creation:
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 }
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다