|
@@ -3162,6 +3162,44 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * proc_tid_comm_permission is a special permission function exclusively
|
|
|
+ * used for the node /proc/<pid>/task/<tid>/comm.
|
|
|
+ * It bypasses generic permission checks in the case where a task of the same
|
|
|
+ * task group attempts to access the node.
|
|
|
+ * The rationale behind this is that glibc and bionic access this node for
|
|
|
+ * cross thread naming (pthread_set/getname_np(!self)). However, if
|
|
|
+ * PR_SET_DUMPABLE gets set to 0 this node among others becomes uid=0 gid=0,
|
|
|
+ * which locks out the cross thread naming implementation.
|
|
|
+ * This function makes sure that the node is always accessible for members of
|
|
|
+ * same thread group.
|
|
|
+ */
|
|
|
+static int proc_tid_comm_permission(struct inode *inode, int mask)
|
|
|
+{
|
|
|
+ bool is_same_tgroup;
|
|
|
+ struct task_struct *task;
|
|
|
+
|
|
|
+ task = get_proc_task(inode);
|
|
|
+ if (!task)
|
|
|
+ return -ESRCH;
|
|
|
+ is_same_tgroup = same_thread_group(current, task);
|
|
|
+ put_task_struct(task);
|
|
|
+
|
|
|
+ if (likely(is_same_tgroup && !(mask & MAY_EXEC))) {
|
|
|
+ /* This file (/proc/<pid>/task/<tid>/comm) can always be
|
|
|
+ * read or written by the members of the corresponding
|
|
|
+ * thread group.
|
|
|
+ */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return generic_permission(inode, mask);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct inode_operations proc_tid_comm_inode_operations = {
|
|
|
+ .permission = proc_tid_comm_permission,
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* Tasks
|
|
|
*/
|
|
@@ -3180,7 +3218,9 @@ static const struct pid_entry tid_base_stuff[] = {
|
|
|
#ifdef CONFIG_SCHED_DEBUG
|
|
|
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
|
|
|
#endif
|
|
|
- REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
|
|
|
+ NOD("comm", S_IFREG|S_IRUGO|S_IWUSR,
|
|
|
+ &proc_tid_comm_inode_operations,
|
|
|
+ &proc_pid_set_comm_operations, {}),
|
|
|
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
|
|
|
ONE("syscall", S_IRUSR, proc_pid_syscall),
|
|
|
#endif
|