[Devel] [PATCH RHEL7 COMMIT] signal/ve: allow to send signal from another ve namespace

Konstantin Khorenko khorenko at virtuozzo.com
Wed Nov 18 04:58:37 PST 2015


The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.9.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.9.10
------>
commit 3625fff553fb887be336305c72adc29409938f59
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Wed Nov 18 16:58:37 2015 +0400

    signal/ve: allow to send signal from another ve namespace
    
    CRIU sends SIGKILL to container's init process as a part of
    cleanup process if restoring failed.
    CRIU does this from a different ve, which is currently not allowed
    without any apparent reason. SIGKILL just ignored, thus CRIU
    hangs on wait for process being killed.
    So this patch allows such signals.
    
    https://jira.sw.ru/browse/PSBM-40896
    
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
    
    khorenko@: (aryabinin@, avagin@, skinsbursky@ conversation summary)
    basically it reverts commit fd3207d650434ac82f2c897cadd5607e67f2c274
        ve: Ignore signals from wrong ve
    
        Port sig_ve_ignored().
        This is a part of 74-diff-ve-mix-combined.
        https://jira.sw.ru/browse/PSBM-17903
        Signed-off-by: Kirill Tkhai <ktkhai at parallels.com>
    
    which was a port of port ... of port of original patch:
    
    date: 2007/05/18 13:24:17;  author: dev;  state: Exp;
    Patch from Denis Lunev <den at openvz.org>
    [VE] VE init signal delivery reworked to be similar to host
    Prevent VE init from receiving unexpected signals sent from VE
    including fatal ones. Signals sent from VE0 are still allowed,
    e.g. for fast VE stop.
    Fix for sys_reboot called from VE to force VE death
    (SIGKILL is sent in the context of VE).
    
    http://bugzilla.openvz.org/show_bug.cgi?id=533
    
    So we don't break the original logic as well here:
    [root at fc22-vm ~]# unshare --fork -p
    [root at fc22-vm ~]# kill -9 1
    [root at fc22-vm ~]# kill -9 1
    [root at fc22-vm ~]# kill -9 1
    [root at fc22-vm ~]# kill -9 1
    [root at fc22-vm ~]# kill -USR1 1
    [root at fc22-vm ~]# kill -USR1 1
    [root at fc22-vm ~]#
---
 include/linux/ve_proto.h |  3 ---
 kernel/signal.c          | 27 ++-------------------------
 2 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/include/linux/ve_proto.h b/include/linux/ve_proto.h
index 0f5898e..153f18b 100644
--- a/include/linux/ve_proto.h
+++ b/include/linux/ve_proto.h
@@ -31,7 +31,6 @@ static inline bool ve_is_super(struct ve_struct *ve)
 }
 
 #define get_exec_env()		(current->task_ve)
-#define get_env_init(ve)	(ve->ve_ns->pid_ns->child_reaper)
 
 const char *ve_name(struct ve_struct *ve);
 
@@ -122,8 +121,6 @@ static inline struct ve_struct *get_exec_env(void)
 	return NULL;
 }
 
-#define get_env_init(ve)	(ve->ve_ns->pid_ns->child_reaper)
-
 static inline bool ve_is_super(struct ve_struct *ve)
 {
 	return true;
diff --git a/kernel/signal.c b/kernel/signal.c
index 357f164..49fbdb0 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -55,27 +55,6 @@ static inline int is_si_special(const struct siginfo *info);
 
 int print_fatal_signals __read_mostly;
 
-static int sig_ve_ignored(int sig, struct siginfo *info, struct task_struct *t)
-{
-	struct ve_struct *ve;
-
-	/* always allow signals from the kernel */
-	if (info == SEND_SIG_FORCED ||
-	    (!is_si_special(info) && SI_FROMKERNEL(info)))
-		return 0;
-
-	ve = get_exec_env();
-	if (ve_is_super(ve))
-		return 0;
-	rcu_read_lock();
-	if (ve->ve_ns && get_env_init(ve) != t) {
-		rcu_read_unlock();
-		return 0;
-	}
-	rcu_read_unlock();
-	return !sig_user_defined(t, sig) || sig_kernel_only(sig);
-}
-
 static void __user *sig_handler(struct task_struct *t, int sig)
 {
 	return t->sighand->action[sig - 1].sa.sa_handler;
@@ -1361,8 +1340,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 	rcu_read_unlock();
 
 	if (!ret && sig)
-		ret = sig_ve_ignored(sig, info, p) ? 0 :
-			do_send_sig_info(sig, info, p, true);
+		ret = do_send_sig_info(sig, info, p, true);
 
 	return ret;
 }
@@ -2976,8 +2954,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
 		 * probe.  No signal is actually delivered.
 		 */
 		if (!error && sig) {
-			if (!sig_ve_ignored(sig, info, p))
-				error = do_send_sig_info(sig, info, p, false);
+			error = do_send_sig_info(sig, info, p, false);
 			/*
 			 * If lock_task_sighand() failed we pretend the task
 			 * dies after receiving the signal. The window is tiny,


More information about the Devel mailing list