ユーザーがrootでない場合、hidepid = 2を使用して実行権限のみを持つバイナリプロセスがまだ「ps」に隠されているのはなぜですか?

ユーザーがrootでない場合、hidepid = 2を使用して実行権限のみを持つバイナリプロセスがまだ「ps」に隠されているのはなぜですか?

ユーザーが自分のプロセスのみを表示できるように、/procをhidepid = 2としてマウントしました。私が使用したい特定のバイナリはrwx--x--x権限に制限されているので、所有者(root)だけを読むことができますが、他のユーザーは実行できます。通常のユーザーであれば問題なく実行できますが、「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 }

関連情報