If we checkpoint a task that has a pending signal with si_code < 0 (easily caused by raising a blocked signal) we hit the BUG() in fill_siginfo. In this case, we should checkpoint and restore si_pid, si_uid, and the members of the si_val union. Signed-off-by: Nathan Lynch <ntl@xxxxxxxxx> --- kernel/signal.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 40 insertions(+), 0 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 85757e1..cc7aee9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2920,6 +2920,25 @@ static void fill_siginfo(struct ckpt_siginfo *si, const siginfo_t *info) si->csi_code = info->si_code; /* TODO: convert info->si_uid to uid_objref */ + if (info->si_code < 0) { + switch(info->si_code) { + case SI_QUEUE: + case SI_TIMER: + case SI_MESGQ: + case SI_ASYNCIO: + case SI_SIGIO: + case SI_TKILL: + case SI_DETHREAD: + si->csi_pid = info->si_pid; + si->csi_uid = info->si_uid; + si->csi_ptr = (unsigned long)info->si_ptr; + si->csi_int = info->si_int; + break; + default: + BUG(); + } + return; + } switch (info->si_code & __SI_MASK) { case __SI_KILL: @@ -2972,6 +2991,27 @@ static int load_siginfo(siginfo_t *info, const struct ckpt_siginfo *si) info->si_code = si->csi_code; /* TODO: validate remaining signal fields */ + if (info->si_code < 0) { + switch(info->si_code) { + case SI_QUEUE: + case SI_TIMER: + case SI_MESGQ: + case SI_ASYNCIO: + case SI_SIGIO: + case SI_TKILL: + case SI_DETHREAD: + info->si_pid = si->csi_pid; + info->si_uid = si->csi_uid; + info->si_ptr = (void __user *) + (unsigned long)si->csi_ptr; + info->si_int = si->csi_int; + break; + default: + return -EINVAL; + break; + } + return 0; + } switch (info->si_code & __SI_MASK) { case __SI_KILL: -- 1.7.1.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers