Skip to content

Commit

Permalink
Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/ebiederm/user-namespace

Pull core signal handling updates from Eric Biederman:
 "It was observed that a periodic timer in combination with a
  sufficiently expensive fork could prevent fork from every completing.
  This contains the changes to remove the need for that restart.

  This set of changes is split into several parts:

   - The first part makes PIDTYPE_TGID a proper pid type instead
     something only for very special cases. The part starts using
     PIDTYPE_TGID enough so that in __send_signal where signals are
     actually delivered we know if the signal is being sent to a a group
     of processes or just a single process.

   - With that prep work out of the way the logic in fork is modified so
     that fork logically makes signals received while it is running
     appear to be received after the fork completes"

* 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (22 commits)
  signal: Don't send signals to tasks that don't exist
  signal: Don't restart fork when signals come in.
  fork: Have new threads join on-going signal group stops
  fork: Skip setting TIF_SIGPENDING in ptrace_init_task
  signal: Add calculate_sigpending()
  fork: Unconditionally exit if a fatal signal is pending
  fork: Move and describe why the code examines PIDNS_ADDING
  signal: Push pid type down into complete_signal.
  signal: Push pid type down into __send_signal
  signal: Push pid type down into send_signal
  signal: Pass pid type into do_send_sig_info
  signal: Pass pid type into send_sigio_to_task & send_sigurg_to_task
  signal: Pass pid type into group_send_sig_info
  signal: Pass pid and pid type into send_sigqueue
  posix-timers: Noralize good_sigevent
  signal: Use PIDTYPE_TGID to clearly store where file signals will be sent
  pid: Implement PIDTYPE_TGID
  pids: Move the pgrp and session pid pointers from task_struct to signal_struct
  kvm: Don't open code task_pid in kvm_vcpu_ioctl
  pids: Compute task_tgid using signal->leader_pid
  ...
  • Loading branch information
torvalds committed Aug 21, 2018
2 parents 40fafdc + 84fe4cc commit 0214f46
Show file tree
Hide file tree
Showing 33 changed files with 294 additions and 201 deletions.
4 changes: 2 additions & 2 deletions arch/ia64/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ void foo(void)

DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
DEFINE(IA64_TASK_TGIDLINK_OFFSET, offsetof (struct task_struct, pids[PIDTYPE_PID].pid));
DEFINE(IA64_TASK_THREAD_PID_OFFSET,offsetof (struct task_struct, thread_pid));
DEFINE(IA64_PID_LEVEL_OFFSET, offsetof (struct pid, level));
DEFINE(IA64_PID_UPID_OFFSET, offsetof (struct pid, numbers[0]));
DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
Expand All @@ -68,6 +67,7 @@ void foo(void)
DEFINE(IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,offsetof (struct signal_struct,
group_stop_count));
DEFINE(IA64_SIGNAL_SHARED_PENDING_OFFSET,offsetof (struct signal_struct, shared_pending));
DEFINE(IA64_SIGNAL_PIDS_TGID_OFFSET, offsetof (struct signal_struct, pids[PIDTYPE_TGID]));

BLANK();

Expand Down
12 changes: 6 additions & 6 deletions arch/ia64/kernel/fsys.S
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ ENTRY(fsys_getpid)
.prologue
.altrp b6
.body
add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
add r17=IA64_TASK_SIGNAL_OFFSET,r16
;;
ld8 r17=[r17] // r17 = current->group_leader
ld8 r17=[r17] // r17 = current->signal
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
;;
ld4 r9=[r9]
add r17=IA64_TASK_TGIDLINK_OFFSET,r17
add r17=IA64_SIGNAL_PIDS_TGID_OFFSET,r17
;;
and r9=TIF_ALLWORK_MASK,r9
ld8 r17=[r17] // r17 = current->group_leader->pids[PIDTYPE_PID].pid
ld8 r17=[r17] // r17 = current->signal->pids[PIDTYPE_TGID]
;;
add r8=IA64_PID_LEVEL_OFFSET,r17
;;
Expand All @@ -96,11 +96,11 @@ ENTRY(fsys_set_tid_address)
.altrp b6
.body
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
add r17=IA64_TASK_TGIDLINK_OFFSET,r16
add r17=IA64_TASK_THREAD_PID_OFFSET,r16
;;
ld4 r9=[r9]
tnat.z p6,p7=r32 // check argument register for being NaT
ld8 r17=[r17] // r17 = current->pids[PIDTYPE_PID].pid
ld8 r17=[r17] // r17 = current->thread_pid
;;
and r9=TIF_ALLWORK_MASK,r9
add r8=IA64_PID_LEVEL_OFFSET,r17
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/perf_cpum_sf.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ static void cpumsf_output_event_pid(struct perf_event *event,
goto out;

/* Update the process ID (see also kernel/events/core.c) */
data->tid_entry.pid = cpumsf_pid_type(event, pid, __PIDTYPE_TGID);
data->tid_entry.pid = cpumsf_pid_type(event, pid, PIDTYPE_TGID);
data->tid_entry.tid = cpumsf_pid_type(event, pid, PIDTYPE_PID);

perf_output_sample(&handle, &header, data, event);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -3217,7 +3217,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
goto out;

if (on) {
__f_setown(file, task_pid(current), PIDTYPE_PID, 0);
__f_setown(file, task_pid(current), PIDTYPE_TGID, 0);
tfile->flags |= TUN_FASYNC;
} else
tfile->flags &= ~TUN_FASYNC;
Expand Down
1 change: 1 addition & 0 deletions drivers/platform/x86/thinkpad_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/sysrq.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static void send_sig_all(int sig)
if (is_global_init(p))
continue;

do_send_sig_info(sig, SEND_SIG_FORCED, p, true);
do_send_sig_info(sig, SEND_SIG_FORCED, p, PIDTYPE_MAX);
}
read_unlock(&tasklist_lock);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2113,7 +2113,7 @@ static int __tty_fasync(int fd, struct file *filp, int on)
type = PIDTYPE_PGID;
} else {
pid = task_pid(current);
type = PIDTYPE_PID;
type = PIDTYPE_TGID;
}
get_pid(pid);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Expand Down
1 change: 1 addition & 0 deletions fs/autofs/autofs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/uaccess.h>
Expand Down
1 change: 1 addition & 0 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,7 @@ static int de_thread(struct task_struct *tsk)
*/
tsk->pid = leader->pid;
change_pid(tsk, PIDTYPE_PID, task_pid(leader));
transfer_pid(leader, tsk, PIDTYPE_TGID);
transfer_pid(leader, tsk, PIDTYPE_PGID);
transfer_pid(leader, tsk, PIDTYPE_SID);

Expand Down
74 changes: 39 additions & 35 deletions fs/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
struct pid *pid = NULL;
int who = arg, ret = 0;

type = PIDTYPE_PID;
type = PIDTYPE_TGID;
if (who < 0) {
/* avoid overflow below */
if (who == INT_MIN)
Expand All @@ -143,7 +143,7 @@ EXPORT_SYMBOL(f_setown);

void f_delown(struct file *filp)
{
f_modown(filp, NULL, PIDTYPE_PID, 1);
f_modown(filp, NULL, PIDTYPE_TGID, 1);
}

pid_t f_getown(struct file *filp)
Expand Down Expand Up @@ -171,11 +171,11 @@ static int f_setown_ex(struct file *filp, unsigned long arg)

switch (owner.type) {
case F_OWNER_TID:
type = PIDTYPE_MAX;
type = PIDTYPE_PID;
break;

case F_OWNER_PID:
type = PIDTYPE_PID;
type = PIDTYPE_TGID;
break;

case F_OWNER_PGRP:
Expand Down Expand Up @@ -206,11 +206,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
read_lock(&filp->f_owner.lock);
owner.pid = pid_vnr(filp->f_owner.pid);
switch (filp->f_owner.pid_type) {
case PIDTYPE_MAX:
case PIDTYPE_PID:
owner.type = F_OWNER_TID;
break;

case PIDTYPE_PID:
case PIDTYPE_TGID:
owner.type = F_OWNER_PID;
break;

Expand Down Expand Up @@ -723,7 +723,7 @@ static inline int sigio_perm(struct task_struct *p,

static void send_sigio_to_task(struct task_struct *p,
struct fown_struct *fown,
int fd, int reason, int group)
int fd, int reason, enum pid_type type)
{
/*
* F_SETSIG can change ->signum lockless in parallel, make
Expand Down Expand Up @@ -767,11 +767,11 @@ static void send_sigio_to_task(struct task_struct *p,
else
si.si_band = mangle_poll(band_table[reason - POLL_IN]);
si.si_fd = fd;
if (!do_send_sig_info(signum, &si, p, group))
if (!do_send_sig_info(signum, &si, p, type))
break;
/* fall-through: fall back on the old plain SIGIO signal */
case 0:
do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, type);
}
}

Expand All @@ -780,63 +780,67 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
struct task_struct *p;
enum pid_type type;
struct pid *pid;
int group = 1;

read_lock(&fown->lock);

type = fown->pid_type;
if (type == PIDTYPE_MAX) {
group = 0;
type = PIDTYPE_PID;
}

pid = fown->pid;
if (!pid)
goto out_unlock_fown;

read_lock(&tasklist_lock);
do_each_pid_task(pid, type, p) {
send_sigio_to_task(p, fown, fd, band, group);
} while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);

if (type <= PIDTYPE_TGID) {
rcu_read_lock();
p = pid_task(pid, PIDTYPE_PID);
if (p)
send_sigio_to_task(p, fown, fd, band, type);
rcu_read_unlock();
} else {
read_lock(&tasklist_lock);
do_each_pid_task(pid, type, p) {
send_sigio_to_task(p, fown, fd, band, type);
} while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);
}
out_unlock_fown:
read_unlock(&fown->lock);
}

static void send_sigurg_to_task(struct task_struct *p,
struct fown_struct *fown, int group)
struct fown_struct *fown, enum pid_type type)
{
if (sigio_perm(p, fown, SIGURG))
do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group);
do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, type);
}

int send_sigurg(struct fown_struct *fown)
{
struct task_struct *p;
enum pid_type type;
struct pid *pid;
int group = 1;
int ret = 0;

read_lock(&fown->lock);

type = fown->pid_type;
if (type == PIDTYPE_MAX) {
group = 0;
type = PIDTYPE_PID;
}

pid = fown->pid;
if (!pid)
goto out_unlock_fown;

ret = 1;

read_lock(&tasklist_lock);
do_each_pid_task(pid, type, p) {
send_sigurg_to_task(p, fown, group);
} while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);

if (type <= PIDTYPE_TGID) {
rcu_read_lock();
p = pid_task(pid, PIDTYPE_PID);
if (p)
send_sigurg_to_task(p, fown, type);
rcu_read_unlock();
} else {
read_lock(&tasklist_lock);
do_each_pid_task(pid, type, p) {
send_sigurg_to_task(p, fown, type);
} while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);
}
out_unlock_fown:
read_unlock(&fown->lock);
return ret;
Expand Down
1 change: 1 addition & 0 deletions fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/module.h>
#include <linux/compat.h>
#include <linux/swap.h>
Expand Down
2 changes: 1 addition & 1 deletion fs/locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ lease_setup(struct file_lock *fl, void **priv)
if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa))
*priv = NULL;

__f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
__f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
}

static const struct lock_manager_operations lease_manager_ops = {
Expand Down
3 changes: 2 additions & 1 deletion fs/notify/dnotify/dnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/dnotify.h>
#include <linux/init.h>
#include <linux/spinlock.h>
Expand Down Expand Up @@ -353,7 +354,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
goto out;
}

__f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
__f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);

error = attach_dn(dn, dn_mark, id, fd, filp, mask);
/* !error means that we attached the dn to the dn_mark, so don't free it */
Expand Down
1 change: 1 addition & 0 deletions fs/notify/fanotify/fanotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/mount.h>
#include <linux/sched.h>
#include <linux/sched/user.h>
#include <linux/sched/signal.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/audit.h>
Expand Down
9 changes: 0 additions & 9 deletions include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ extern struct cred init_cred;
#define INIT_CPU_TIMERS(s)
#endif

#define INIT_PID_LINK(type) \
{ \
.node = { \
.next = NULL, \
.pprev = NULL, \
}, \
.pid = &init_struct_pid, \
}

#define INIT_TASK_COMM "swapper"

/* Attach to the init_task data structure for proper alignment */
Expand Down
11 changes: 2 additions & 9 deletions include/linux/pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
enum pid_type
{
PIDTYPE_PID,
PIDTYPE_TGID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX,
/* only valid to __task_pid_nr_ns() */
__PIDTYPE_TGID
};

/*
Expand Down Expand Up @@ -67,12 +66,6 @@ struct pid

extern struct pid init_struct_pid;

struct pid_link
{
struct hlist_node node;
struct pid *pid;
};

static inline struct pid *get_pid(struct pid *pid)
{
if (pid)
Expand Down Expand Up @@ -177,7 +170,7 @@ pid_t pid_vnr(struct pid *pid);
do { \
if ((pid) != NULL) \
hlist_for_each_entry_rcu((task), \
&(pid)->tasks[type], pids[type].node) {
&(pid)->tasks[type], pid_links[type]) {

/*
* Both old and new leaders may be attached to
Expand Down
2 changes: 0 additions & 2 deletions include/linux/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,6 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace)
task_set_jobctl_pending(child, JOBCTL_TRAP_STOP);
else
sigaddset(&child->pending.signal, SIGSTOP);

set_tsk_thread_flag(child, TIF_SIGPENDING);
}
else
child->ptracer_cred = NULL;
Expand Down
Loading

0 comments on commit 0214f46

Please sign in to comment.