19 Star 0 Fork 35

openEuler-RISC-V/criu

forked from src-openEuler/criu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0029-cred-provide-cred-checkpoint-restore-method.patch 7.87 KB
一键复制 编辑 原始数据 按行查看 历史
river 提交于 2022-04-13 15:05 . criu: backport kinds of features/bugfix
From e522deb5680840e878b8f05c66f040cfd3b49d90 Mon Sep 17 00:00:00 2001
From: Jingxian He <hejingxian@huawei.com>
Date: Wed, 19 May 2021 21:47:28 +0800
Subject: [PATCH 29/72] cred: provide cred checkpoint restore method
criu checkpoint/restore the task, it only restore the context instead of
the memory address storing the context.
To handle the problem resulted by CVE bugfix, details:
- https://nvd.nist.gov/vuln/detail/CVE-2016-4565
- https://openfabrics.org/images/2018workshop/presentations/113_MRuhl_JourneytoVerbsIOCTL.pdf
Brief:
Refresh the security context address of file. The infiniband code use
write()` as bi-directional `ioctl()`, there is `struct cred` address
uring `write()` process. However, criu uses some syscall, such as
capset()` and `setgroups()`, to regenerate the new cred, the file
red is fixed by `fcntl(F_SETOWN)`, then the address of new cred is
ifferent from the file.
This patch fix the `struct cred` address checking problem resulted by
VE fixed in infiniband drivers.
Conflict:NA
Reference:https://gitee.com/src-openeuler/criu/pulls/21
Signed-off-by: luolongjun <luolongjun@huawei.com>
Signed-off-by: fu.lin <fu.lin10@huawei.com>
---
criu/config.c | 1 +
criu/cr-restore.c | 35 +++++++++++++++++++++++++++++++++++
criu/crtools.c | 1 +
criu/include/cr_options.h | 1 +
criu/include/fcntl.h | 4 ++++
criu/include/prctl.h | 4 ++++
criu/include/restorer.h | 3 +++
criu/pie/restorer.c | 38 ++++++++++++++++++++++++++++++++++++++
8 files changed, 87 insertions(+)
diff --git a/criu/config.c b/criu/config.c
index 03cad66..cf99fb1 100644
--- a/criu/config.c
+++ b/criu/config.c
@@ -702,6 +702,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
BOOL_OPT("use-fork-pid", &opts.use_fork_pid),
BOOL_OPT("with-notifier", &opts.with_notifier_kup),
BOOL_OPT("dump-char-dev", &opts.dump_char_dev),
+ BOOL_OPT("with-fd-cred", &opts.with_fd_cred),
{},
};
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 2904a75..ac677a1 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -692,6 +692,28 @@ static int __collect_child_pids(struct pstree_item *p, int state, unsigned int *
return 0;
}
+static int collect_child_fds(int state, unsigned int *n, struct pstree_item *me)
+{
+ struct list_head *list = &rsti(me)->fds;
+ struct fdinfo_list_entry *fle, *tmp;
+
+ *n = 0;
+ list_for_each_entry_safe(fle, tmp, list, ps_list) {
+ if (fle->fe->type == state) {
+ int *child;
+
+ child = rst_mem_alloc(sizeof(*child), RM_PRIVATE);
+ if (!child)
+ return -1;
+
+ (*n)++;
+ *child = fle->fe->fd;
+ }
+ }
+
+ return 0;
+}
+
static int collect_child_pids(int state, unsigned int *n)
{
struct pstree_item *pi;
@@ -715,6 +737,12 @@ static int collect_child_pids(int state, unsigned int *n)
return __collect_child_pids(current, state, n);
}
+static int collect_chr_fds(struct pstree_item *me, struct task_restore_args *ta)
+{
+ ta->setcred_pids = (int *)rst_mem_align_cpos(RM_PRIVATE);
+ return collect_child_fds(FD_TYPES__CHR, &ta->setcred_pids_n, me);
+}
+
static int collect_helper_pids(struct task_restore_args *ta)
{
ta->helpers = (pid_t *)rst_mem_align_cpos(RM_PRIVATE);
@@ -939,6 +967,9 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
if (collect_zombie_pids(ta) < 0)
return -1;
+ if (opts.with_fd_cred && collect_chr_fds(current, ta) < 0)
+ return -1;
+
if (collect_inotify_fds(ta) < 0)
return -1;
@@ -3746,6 +3777,10 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
RST_MEM_FIXUP_PPTR(task_args->helpers);
RST_MEM_FIXUP_PPTR(task_args->zombies);
RST_MEM_FIXUP_PPTR(task_args->vma_ios);
+ if (opts.with_fd_cred)
+ RST_MEM_FIXUP_PPTR(task_args->setcred_pids);
+ else
+ task_args->setcred_pids_n = UINT_MAX;
RST_MEM_FIXUP_PPTR(task_args->inotify_fds);
task_args->compatible_mode = core_is_compat(core);
diff --git a/criu/crtools.c b/criu/crtools.c
index dc6d603..ed7bd99 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -453,6 +453,7 @@ usage:
" This feature needs the kernel assistance.\n"
" --dump-char-dev Dump char dev files as normal file with repair cmd\n"
\
+ " --with-fd-cred Allow to make the restored process has the same cred\n"
"\n"
"Check options:\n"
" Without options, \"criu check\" checks availability of absolutely required\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 226acb2..1d6ddcf 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -194,6 +194,7 @@ struct cr_options {
int use_fork_pid;
int with_notifier_kup;
int dump_char_dev;
+ int with_fd_cred;
};
extern struct cr_options opts;
diff --git a/criu/include/fcntl.h b/criu/include/fcntl.h
index 35f8805..568977c 100644
--- a/criu/include/fcntl.h
+++ b/criu/include/fcntl.h
@@ -19,6 +19,10 @@ struct f_owner_ex {
#define F_GETOWNER_UIDS 17
#endif
+#ifndef F_SETCRED
+#define F_SETCRED 18
+#endif
+
/*
* These things are required to compile on CentOS-6
*/
diff --git a/criu/include/prctl.h b/criu/include/prctl.h
index c843f40..81dda9d 100644
--- a/criu/include/prctl.h
+++ b/criu/include/prctl.h
@@ -82,4 +82,8 @@ struct prctl_mm_map {
#define PR_GET_THP_DISABLE 42
#endif
+#ifndef PR_DEFAULT_CRED
+#define PR_DEFAULT_CRED 54
+#endif
+
#endif /* __CR_PRCTL_H__ */
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index a81cc1b..60c1dab 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -193,6 +193,9 @@ struct task_restore_args {
pid_t *zombies;
unsigned int zombies_n;
+ int *setcred_pids;
+ unsigned int setcred_pids_n;
+
int *inotify_fds; /* fds to cleanup inotify events at CR_STATE_RESTORE_SIGCHLD stage */
unsigned int inotify_fds_n;
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index dcc922e..fde6e30 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -101,6 +101,7 @@ static int restore_anon_mapping(VmaEntry *vma_entry, struct vma_names *vma_name)
static struct task_entries *task_entries_local;
static futex_t thread_inprogress;
static futex_t thread_start;
+static futex_t cred_set;
static pid_t *helpers;
static int n_helpers;
static pid_t *zombies;
@@ -365,6 +366,41 @@ static int restore_creds(struct thread_creds_args *args, int procfd, int lsm_typ
return 0;
}
+static int update_cred_ref(struct task_restore_args *ta)
+{
+ int i;
+ int ret;
+ int pid = sys_getpid();
+ long int tid = sys_gettid();
+
+ if (ta->setcred_pids_n == UINT_MAX) {
+ pr_info("no need to keep the same cred \n");
+ return 0;
+ }
+
+ if (pid == tid) {
+ /* let main thread finish cred update first */
+ ret = sys_prctl(PR_DEFAULT_CRED, 0, 0, 0, 0);
+ pr_info("main cred restore \n");
+ futex_set_and_wake(&cred_set, 1);
+ } else {
+ futex_wait_until(&cred_set, 1);
+ pr_info("other cred restore \n");
+ ret = sys_prctl(PR_DEFAULT_CRED, 0, 0, 0, 0);
+ }
+
+ if (ret)
+ return ret;
+
+ pr_info("%ld (%d) is going to update current cred \n", tid, pid);
+
+ for (i = 0; i < ta->setcred_pids_n; i++) {
+ sys_fcntl(ta->setcred_pids[i], F_SETCRED, 0);
+ }
+
+ return 0;
+}
+
/*
* This should be done after creds restore, as
* some creds changes might drop the value back
@@ -742,6 +778,7 @@ long __export_restore_thread(struct thread_restore_args *args)
BUG();
ret = restore_creds(args->creds_args, args->ta->proc_fd, args->ta->lsm_type);
+ ret = ret || update_cred_ref(args->ta);
ret = ret || restore_dumpable_flag(&args->ta->mm);
ret = ret || restore_pdeath_sig(args);
if (ret)
@@ -2221,6 +2258,7 @@ long __export_restore_task(struct task_restore_args *args)
* thus restore* creds _after_ all of the above.
*/
ret = restore_creds(args->t->creds_args, args->proc_fd, args->lsm_type);
+ ret = ret || update_cred_ref(args);
ret = ret || restore_dumpable_flag(&args->mm);
ret = ret || restore_pdeath_sig(args->t);
ret = ret || restore_child_subreaper(args->child_subreaper);
--
2.34.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/openeuler-risc-v/criu.git
git@gitee.com:openeuler-risc-v/criu.git
openeuler-risc-v
criu
criu
master

搜索帮助