[CRIU] [PATCH 4/9] Moved function prepare_sigactions() from here
prakriti goyal
prakritigoyal19 at gmail.com
Mon Mar 16 18:59:31 MSK 2020
From: prakritigoyal19 <prakritigoyal19 at gmail.com>
Signed-off-by: prakritigoyal19 <prakritigoyal19 at gmail.com>
Repo link: https://github.com/prakritigoyal19/criu/tree/sigactions
---
criu/cr-restore.c | 263 +---------------------------------------------
1 file changed, 3 insertions(+), 260 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e5a82775..1af1cab3 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -68,6 +68,7 @@
#include "timerfd.h"
#include "action-scripts.h"
#include "shmem.h"
+#include <compel/compel.h>
#include "aio.h"
#include "lsm.h"
#include "seccomp.h"
@@ -78,10 +79,11 @@
#include "memfd.h"
#include "string.h"
-#include "parasite-syscall.h"
+#include "include/parasite-syscall.h"
#include "files-reg.h"
#include <compel/plugins/std/syscall-codes.h>
#include "compel/include/asm/syscall.h"
+#include "sigaction.h"
#include "protobuf.h"
#include "images/sa.pb-c.h"
@@ -415,265 +417,6 @@ static int populate_pid_proc(void)
return 0;
}
-static rt_sigaction_t sigchld_act;
-/*
- * If parent's sigaction has blocked SIGKILL (which is non-sense),
- * this parent action is non-valid and shouldn't be inherited.
- * Used to mark parent_act* no more valid.
- */
-static rt_sigaction_t parent_act[SIGMAX];
-#ifdef CONFIG_COMPAT
-static rt_sigaction_t_compat parent_act_compat[SIGMAX];
-#endif
-
-static bool sa_inherited(int sig, rt_sigaction_t *sa)
-{
- rt_sigaction_t *pa;
- int i;
-
- if (current == root_item)
- return false; /* XXX -- inherit from CRIU? */
-
- pa = &parent_act[sig];
-
- /* Omitting non-valid sigaction */
- if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
- return false;
-
- for (i = 0; i < _KNSIG_WORDS; i++)
- if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
- return false;
-
- return pa->rt_sa_handler == sa->rt_sa_handler &&
- pa->rt_sa_flags == sa->rt_sa_flags &&
- pa->rt_sa_restorer == sa->rt_sa_restorer;
-}
-
-static int restore_native_sigaction(int sig, SaEntry *e)
-{
- rt_sigaction_t act;
- int ret;
-
- ASSIGN_TYPED(act.rt_sa_handler, decode_pointer(e->sigaction));
- ASSIGN_TYPED(act.rt_sa_flags, e->flags);
- ASSIGN_TYPED(act.rt_sa_restorer, decode_pointer(e->restorer));
- BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
- memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
-
- if (sig == SIGCHLD) {
- sigchld_act = act;
- return 0;
- }
-
- if (sa_inherited(sig - 1, &act))
- return 1;
-
- /*
- * A pure syscall is used, because glibc
- * sigaction overwrites se_restorer.
- */
- ret = syscall(SYS_rt_sigaction, sig, &act, NULL, sizeof(k_rtsigset_t));
- if (ret < 0) {
- pr_perror("Can't restore sigaction");
- return ret;
- }
-
- parent_act[sig - 1] = act;
- /* Mark SIGKILL blocked which makes compat sigaction non-valid */
-#ifdef CONFIG_COMPAT
- parent_act_compat[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
-#endif
-
- return 1;
-}
-
-static void *stack32;
-
-#ifdef CONFIG_COMPAT
-static bool sa_compat_inherited(int sig, rt_sigaction_t_compat *sa)
-{
- rt_sigaction_t_compat *pa;
- int i;
-
- if (current == root_item)
- return false;
-
- pa = &parent_act_compat[sig];
-
- /* Omitting non-valid sigaction */
- if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
- return false;
-
- for (i = 0; i < _KNSIG_WORDS; i++)
- if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
- return false;
-
- return pa->rt_sa_handler == sa->rt_sa_handler &&
- pa->rt_sa_flags == sa->rt_sa_flags &&
- pa->rt_sa_restorer == sa->rt_sa_restorer;
-}
-
-static int restore_compat_sigaction(int sig, SaEntry *e)
-{
- rt_sigaction_t_compat act;
- int ret;
-
- ASSIGN_TYPED(act.rt_sa_handler, (u32)e->sigaction);
- ASSIGN_TYPED(act.rt_sa_flags, e->flags);
- ASSIGN_TYPED(act.rt_sa_restorer, (u32)e->restorer);
- BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
- memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
-
- if (sig == SIGCHLD) {
- memcpy(&sigchld_act, &act, sizeof(rt_sigaction_t_compat));
- return 0;
- }
-
- if (sa_compat_inherited(sig - 1, &act))
- return 1;
-
- if (!stack32) {
- stack32 = alloc_compat_syscall_stack();
- if (!stack32)
- return -1;
- }
-
- ret = arch_compat_rt_sigaction(stack32, sig, &act);
- if (ret < 0) {
- pr_err("Can't restore compat sigaction: %d\n", ret);
- return ret;
- }
-
- parent_act_compat[sig - 1] = act;
- /* Mark SIGKILL blocked which makes native sigaction non-valid */
- parent_act[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
-
- return 1;
-}
-#else
-static int restore_compat_sigaction(int sig, SaEntry *e)
-{
- return -1;
-}
-#endif
-
-static int prepare_sigactions_from_core(TaskCoreEntry *tc)
-{
- int sig, i;
-
- if (tc->n_sigactions != SIGMAX - 2) {
- pr_err("Bad number of sigactions in the image (%d, want %d)\n",
- (int)tc->n_sigactions, SIGMAX - 2);
- return -1;
- }
-
- pr_info("Restore on-core sigactions for %d\n", vpid(current));
-
- for (sig = 1, i = 0; sig <= SIGMAX; sig++) {
- int ret;
- SaEntry *e;
- bool sigaction_is_compat;
-
- if (sig == SIGKILL || sig == SIGSTOP)
- continue;
-
- e = tc->sigactions[i++];
- sigaction_is_compat = e->has_compat_sigaction && e->compat_sigaction;
- if (sigaction_is_compat)
- ret = restore_compat_sigaction(sig, e);
- else
- ret = restore_native_sigaction(sig, e);
-
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-/* Returns number of restored signals, -1 or negative errno on fail */
-static int restore_one_sigaction(int sig, struct cr_img *img, int pid)
-{
- bool sigaction_is_compat;
- SaEntry *e;
- int ret = 0;
-
- BUG_ON(sig == SIGKILL || sig == SIGSTOP);
-
- ret = pb_read_one_eof(img, &e, PB_SIGACT);
- if (ret == 0) {
- if (sig != SIGMAX_OLD + 1) { /* backward compatibility */
- pr_err("Unexpected EOF %d\n", sig);
- return -1;
- }
- pr_warn("This format of sigacts-%d.img is deprecated\n", pid);
- return -1;
- }
- if (ret < 0)
- return ret;
-
- sigaction_is_compat = e->has_compat_sigaction && e->compat_sigaction;
- if (sigaction_is_compat)
- ret = restore_compat_sigaction(sig, e);
- else
- ret = restore_native_sigaction(sig, e);
-
- sa_entry__free_unpacked(e, NULL);
-
- return ret;
-}
-
-static int prepare_sigactions_from_image(void)
-{
- int pid = vpid(current);
- struct cr_img *img;
- int sig, rst = 0;
- int ret = 0;
-
- pr_info("Restore sigacts for %d\n", pid);
-
- img = open_image(CR_FD_SIGACT, O_RSTR, pid);
- if (!img)
- return -1;
-
- for (sig = 1; sig <= SIGMAX; sig++) {
- if (sig == SIGKILL || sig == SIGSTOP)
- continue;
-
- ret = restore_one_sigaction(sig, img, pid);
- if (ret < 0)
- break;
- if (ret)
- rst++;
- }
-
- pr_info("Restored %d/%d sigacts\n", rst,
- SIGMAX - 3 /* KILL, STOP and CHLD */);
-
- close_image(img);
- return ret;
-}
-
-static int prepare_sigactions(CoreEntry *core)
-{
- int ret;
-
- if (!task_alive(current))
- return 0;
-
- if (core->tc->n_sigactions != 0)
- ret = prepare_sigactions_from_core(core->tc);
- else
- ret = prepare_sigactions_from_image();
-
- if (stack32) {
- free_compat_syscall_stack(stack32);
- stack32 = NULL;
- }
-
- return ret;
-}
-
static int __collect_child_pids(struct pstree_item *p, int state, unsigned int *n)
{
struct pstree_item *pi;
--
2.17.1
More information about the CRIU
mailing list