[CRIU] [PATCH 04/17] dump: get tasks ids from parasite
Andrey Vagin
avagin at openvz.org
Fri Oct 31 02:14:22 PDT 2014
We have two reason for that:
* parsing of /proc/pid/status is slow
* parasite returns ids from a target userns
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
arch/arm/syscall.def | 2 ++
arch/x86/syscall-x86-64.def | 2 ++
cr-dump.c | 31 ++++++++++++-------------------
include/crtools.h | 1 +
include/parasite.h | 10 +++++-----
parasite-syscall.c | 10 ++++++++++
pie/parasite.c | 16 ++++++++++++++++
security.c | 5 +++++
8 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/arch/arm/syscall.def b/arch/arm/syscall.def
index 3b2d1ed..2eed6cf 100644
--- a/arch/arm/syscall.def
+++ b/arch/arm/syscall.def
@@ -54,7 +54,9 @@ readlink 78 85 (const char *path, char *buf, int bufsize)
umask 166 60 (int mask)
getgroups 158 205 (int gsize, unsigned int *groups)
setresuid 147 164 (int uid, int euid, int suid)
+getresuid 148 165 (int *uid, int *euid, int *suid)
setresgid 149 170 (int gid, int egid, int sgid)
+getresgid 150 171 (int *gid, int *egid, int *sgid)
getpgid 155 132 (pid_t pid)
setfsuid 151 138 (int fsuid)
setfsgid 152 139 (int fsgid)
diff --git a/arch/x86/syscall-x86-64.def b/arch/x86/syscall-x86-64.def
index c780c40..1404123 100644
--- a/arch/x86/syscall-x86-64.def
+++ b/arch/x86/syscall-x86-64.def
@@ -54,7 +54,9 @@ __NR_readlink 89 sys_readlink (const char *path, char *buf, int bufsize)
__NR_umask 95 sys_umask (int mask)
__NR_getgroups 115 sys_getgroups (int gsize, unsigned int *groups)
__NR_setresuid 117 sys_setresuid (int uid, int euid, int suid)
+__NR_getresuid 118 sys_getresuid (int *uid, int *euid, int *suid)
__NR_setresgid 119 sys_setresgid (int gid, int egid, int sgid)
+__NR_getresgid 120 sys_getresgid (int *gid, int *egid, int *sgid)
__NR_getpgid 121 sys_getpgid (pid_t pid)
__NR_setfsuid 122 sys_setfsuid (int fsuid)
__NR_setfsgid 123 sys_setfsgid (int fsgid)
diff --git a/cr-dump.c b/cr-dump.c
index 7d33e3d..a40b5ae 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -501,20 +501,10 @@ err:
}
static int dump_task_creds(struct parasite_ctl *ctl,
- const struct cr_imgset *fds,
- struct proc_status_creds *cr)
+ const struct cr_imgset *fds)
{
CredsEntry ce = CREDS_ENTRY__INIT;
- ce.uid = cr->uids[0];
- ce.gid = cr->gids[0];
- ce.euid = cr->uids[1];
- ce.egid = cr->gids[1];
- ce.suid = cr->uids[2];
- ce.sgid = cr->gids[2];
- ce.fsuid = cr->uids[3];
- ce.fsgid = cr->gids[3];
-
pr_info("\n");
pr_info("Dumping creds for %d)\n", ctl->pid.real);
pr_info("----------------------------------------\n");
@@ -1475,7 +1465,6 @@ static int dump_one_task(struct pstree_item *item)
struct cr_imgset *cr_imgset = NULL;
struct parasite_drain_fd *dfds = NULL;
struct proc_posix_timers_stat proc_args;
- struct proc_status_creds cr;
INIT_LIST_HEAD(&vmas.h);
vmas.nr = 0;
@@ -1495,13 +1484,17 @@ static int dump_one_task(struct pstree_item *item)
if (ret < 0)
goto err;
- ret = parse_pid_status(pid, &cr);
- if (ret)
- goto err;
+ if (!cr_user_is_root()) {
+ struct proc_status_creds cr;
- if (!may_dump(&cr)) {
- pr_err("Check uid (pid: %d) failed\n", pid);
- goto err;
+ ret = parse_pid_status(pid, &cr);
+ if (ret)
+ goto err;
+
+ if (!may_dump(&cr)) {
+ pr_err("Check uid (pid: %d) failed\n", pid);
+ goto err;
+ }
}
ret = collect_mappings(pid, &vmas);
@@ -1626,7 +1619,7 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure;
}
- ret = dump_task_creds(parasite_ctl, cr_imgset, &cr);
+ ret = dump_task_creds(parasite_ctl, cr_imgset);
if (ret) {
pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
goto err;
diff --git a/include/crtools.h b/include/crtools.h
index a51886e..f4b09a3 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -29,5 +29,6 @@ struct proc_status_creds;
extern bool may_dump(struct proc_status_creds *);
struct _CredsEntry;
extern bool may_restore(struct _CredsEntry *);
+extern bool cr_user_is_root(void);
#endif /* __CR_CRTOOLS_H__ */
diff --git a/include/parasite.h b/include/parasite.h
index 44be00c..7b3e668 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -169,10 +169,8 @@ struct parasite_dump_misc {
* and still fit the struct in one page
*/
#define PARASITE_MAX_GROUPS \
- (PAGE_SIZE \
- - sizeof(unsigned int) /* cap_last_cap */ \
- - 4 * CR_CAP_SIZE * sizeof(u32) /* cap_{inh,prm,eff,bnd} */ \
- - 2 * sizeof(unsigned int) /* secbits, ngroups*/ \
+ (PAGE_SIZE - \
+ offsetof(struct parasite_dump_creds, groups) \
) / sizeof(unsigned int) /* groups */
struct parasite_dump_creds {
@@ -183,9 +181,11 @@ struct parasite_dump_creds {
u32 cap_eff[CR_CAP_SIZE];
u32 cap_bnd[CR_CAP_SIZE];
+ int uids[4];
+ int gids[4];
unsigned int secbits;
unsigned int ngroups;
- unsigned int groups[PARASITE_MAX_GROUPS];
+ unsigned int groups[0];
};
static inline void copy_sas(ThreadSasEntry *dst, const stack_t *src)
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 063cf47..d17db0b 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -762,6 +762,16 @@ int parasite_dump_creds(struct parasite_ctl *ctl, CredsEntry *ce)
BUILD_BUG_ON(sizeof(ce->groups[0]) != sizeof(pc->groups[0]));
ce->groups = pc->groups;
+
+ ce->uid = pc->uids[0];
+ ce->gid = pc->gids[0];
+ ce->euid = pc->uids[1];
+ ce->egid = pc->gids[1];
+ ce->suid = pc->uids[2];
+ ce->sgid = pc->gids[2];
+ ce->fsuid = pc->uids[3];
+ ce->fsgid = pc->gids[3];
+
return 0;
}
diff --git a/pie/parasite.c b/pie/parasite.c
index 7f1b80a..9557c55 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -236,6 +236,22 @@ static int dump_creds(struct parasite_dump_creds *args)
return -1;
}
+ ret = sys_getresuid(&args->uids[0], &args->uids[1], &args->uids[2]);
+ if (ret) {
+ pr_err("Unable to get uids: %d\n", ret);
+ return -1;
+ }
+
+ args->uids[3] = sys_setfsuid(-1L);
+
+ ret = sys_getresgid(&args->gids[0], &args->gids[1], &args->gids[2]);
+ if (ret) {
+ pr_err("Unable to get uids: %d\n", ret);
+ return -1;
+ }
+
+ args->gids[3] = sys_setfsgid(-1L);
+
return 0;
grps_err:
diff --git a/security.c b/security.c
index a801005..5189846 100644
--- a/security.c
+++ b/security.c
@@ -150,6 +150,11 @@ static bool check_caps(u32 *inh, u32 *eff, u32 *prm)
return true;
}
+bool cr_user_is_root()
+{
+ return cr_uid == 0 && cr_gid == 0;
+}
+
bool may_dump(struct proc_status_creds *creds)
{
return check_uids(creds->uids[0], creds->uids[1], creds->uids[2]) &&
--
1.9.3
More information about the CRIU
mailing list