PROC_TGID_ATTR_EXEC,
PROC_TGID_ATTR_FSCREATE,
PROC_TGID_ATTR_KEYCREATE,
+ PROC_TGID_ATTR_SOCKCREATE,
#endif
#ifdef CONFIG_AUDITSYSCALL
PROC_TGID_LOGINUID,
PROC_TID_ATTR_EXEC,
PROC_TID_ATTR_FSCREATE,
PROC_TID_ATTR_KEYCREATE,
+ PROC_TID_ATTR_SOCKCREATE,
#endif
#ifdef CONFIG_AUDITSYSCALL
PROC_TID_LOGINUID,
E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
{0,0,NULL,0}
};
static struct pid_entry tid_attr_stuff[] = {
E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
{0,0,NULL,0}
};
#endif
{
struct task_struct *task;
int allowed = 0;
- /* Allow access to a task's file descriptors if either we may
- * use ptrace attach to the process and find out that
- * information, or if the task cannot possibly be ptraced
- * allow access if we have the proper capability.
+ /* Allow access to a task's file descriptors if it is us or we
+ * may use ptrace attach to the process and find out that
+ * information.
*/
task = get_proc_task(inode);
- if (task == current)
- allowed = 1;
- if (task && !allowed) {
- int alive;
-
- task_lock(task);
- alive = !!task->mm;
- task_unlock(task);
- if (alive)
- /* For a living task obey ptrace_may_attach */
- allowed = ptrace_may_attach(task);
- else
- /* For a special task simply check the capability */
- allowed = capable(CAP_SYS_PTRACE);
- }
- if (task)
+ if (task) {
+ allowed = ptrace_may_attach(task);
put_task_struct(task);
+ }
return allowed;
}
case PROC_TGID_ATTR_FSCREATE:
case PROC_TID_ATTR_KEYCREATE:
case PROC_TGID_ATTR_KEYCREATE:
+ case PROC_TID_ATTR_SOCKCREATE:
+ case PROC_TGID_ATTR_SOCKCREATE:
inode->i_fop = &proc_pid_attr_operations;
break;
#endif
* In the case of a seek we start with the leader and walk nr
* threads past it.
*/
-static struct task_struct *first_tid(struct task_struct *leader, int tid, int nr)
+static struct task_struct *first_tid(struct task_struct *leader,
+ int tid, int nr)
{
- struct task_struct *pos = NULL;
- read_lock(&tasklist_lock);
+ struct task_struct *pos;
+ rcu_read_lock();
/* Attempt to start with the pid of a thread */
if (tid && (nr > 0)) {
pos = find_task_by_pid(tid);
- if (pos && (pos->group_leader != leader))
- pos = NULL;
- if (pos)
- nr = 0;
+ if (pos && (pos->group_leader == leader))
+ goto found;
}
/* If nr exceeds the number of threads there is nothing todo */
- if (nr) {
- if (nr >= get_nr_threads(leader))
- goto done;
- }
+ pos = NULL;
+ if (nr && nr >= get_nr_threads(leader))
+ goto out;
- /* If we haven't found our starting place yet start with the
- * leader and walk nr threads forward.
+ /* If we haven't found our starting place yet start
+ * with the leader and walk nr threads forward.
*/
- if (!pos && (nr >= 0))
- pos = leader;
-
- for (; pos && pid_alive(pos); pos = next_thread(pos)) {
- if (--nr > 0)
- continue;
- get_task_struct(pos);
- goto done;
+ for (pos = leader; nr > 0; --nr) {
+ pos = next_thread(pos);
+ if (pos == leader) {
+ pos = NULL;
+ goto out;
+ }
}
- pos = NULL;
-done:
- read_unlock(&tasklist_lock);
+found:
+ get_task_struct(pos);
+out:
+ rcu_read_unlock();
return pos;
}
*/
static struct task_struct *next_tid(struct task_struct *start)
{
- struct task_struct *pos;
- read_lock(&tasklist_lock);
- pos = start;
- if (pid_alive(start))
+ struct task_struct *pos = NULL;
+ rcu_read_lock();
+ if (pid_alive(start)) {
pos = next_thread(start);
- if (pid_alive(pos) && (pos != start->group_leader))
- get_task_struct(pos);
- else
- pos = NULL;
- read_unlock(&tasklist_lock);
+ if (thread_group_leader(pos))
+ pos = NULL;
+ else
+ get_task_struct(pos);
+ }
+ rcu_read_unlock();
put_task_struct(start);
return pos;
}