aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Vagin <avagin@openvz.org>2013-02-27 17:03:12 -0800
committerZiyan <jaraidaniel@gmail.com>2016-10-29 01:33:56 +0200
commitf526744200c533a6d4d0566fb16448b4453154aa (patch)
tree2c333628678f05e5052b767e9cbb2a285d721e9b
parent58717332e4fc43d9eb9024504d93fbe913164eea (diff)
downloadkernel_samsung_tuna-f526744200c533a6d4d0566fb16448b4453154aa.zip
kernel_samsung_tuna-f526744200c533a6d4d0566fb16448b4453154aa.tar.gz
kernel_samsung_tuna-f526744200c533a6d4d0566fb16448b4453154aa.tar.bz2
BACKPORT: signal: allow to send any siginfo to itself
(cherry picked from commit 66dd34ad31e5963d72a700ec3f2449291d322921) The idea is simple. We need to get the siginfo for each signal on checkpointing dump, and then return it back on restore. The first problem is that the kernel doesn't report complete siginfos to userspace. In a signal handler the kernel strips SI_CODE from siginfo. When a siginfo is received from signalfd, it has a different format with fixed sizes of fields. The interface of signalfd was extended. If a signalfd is created with the flag SFD_RAW, it returns siginfo in a raw format. rt_sigqueueinfo looks suitable for restoring signals, but it can't send siginfo with a positive si_code, because these codes are reserved for the kernel. In the real world each person has right to do anything with himself, so I think a process should able to send any siginfo to itself. This patch: The kernel prevents sending of siginfo with positive si_code, because these codes are reserved for kernel. I think we can allow a task to send such a siginfo to itself. This operation should not be dangerous. This functionality is required for restoring signals in checkpoint/restart. Change-Id: I40101d87eeb53ae05cfa0949439577a8f3f58f94 Signed-off-by: Andrey Vagin <avagin@openvz.org> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/signal.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index f15021b..2e522a5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2727,7 +2727,8 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info.si_code >= 0 || info.si_code == SI_TKILL) {
+ if ((info.si_code >= 0 || info.si_code == SI_TKILL) &&
+ (task_pid_vnr(current) != pid)) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info.si_code < 0);
return -EPERM;
@@ -2747,7 +2748,8 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info->si_code >= 0 || info->si_code == SI_TKILL) {
+ if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
+ (task_pid_vnr(current) != pid)) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info->si_code < 0);
return -EPERM;