4

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!

6
  • Nope. Can't reproduce. Both pgrep and ps aux show the process just fine. Arch Linux, kernel: 4.1.6-1-ARCH. I compared with pgrep -u lightdm to test if the mount option was applied. Commented Sep 24, 2015 at 12:50
  • The kernel version may be the reason. I'm using Ubuntu 14.04, with 3.13.0. I'll try with another kernel version to see what happens. Thanks! Commented Sep 24, 2015 at 15:27
  • Funny: I've downloaded an ArchLinux vagrant box, with a 4.1.2 kernel, and the same happens. The user can't see his process when the binary has no read permissions. Sorry to be suspicious, @muru, but are you sure you can't reproduce this issue? Commented Sep 24, 2015 at 15:42
  • Dammit, I'd forgotten the sudo while copying. Yep, I can confirm now. Interestingly, this also happens if the program is owned by me and I don't have read permission. :D Commented Sep 24, 2015 at 18:04
  • @rsuarez, Could you explain why would you want to restrict read permissions on a binary executable for your users? Commented Sep 28, 2015 at 10:03

1 Answer 1

4
+50

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 } 
1
  • 1
    Great explanation. Thanks, I'm marking this as the right answer. Commented Oct 1, 2015 at 14:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.