Commit 77905aae authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

dump: get tasks ids from parasite

We have two reason for that:
* parsing of /proc/pid/status is slow
* parasite returns ids from a target userns
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b0217d4e
...@@ -54,7 +54,9 @@ readlink 78 85 (const char *path, char *buf, int bufsize) ...@@ -54,7 +54,9 @@ readlink 78 85 (const char *path, char *buf, int bufsize)
umask 166 60 (int mask) umask 166 60 (int mask)
getgroups 158 205 (int gsize, unsigned int *groups) getgroups 158 205 (int gsize, unsigned int *groups)
setresuid 147 164 (int uid, int euid, int suid) 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) setresgid 149 170 (int gid, int egid, int sgid)
getresgid 150 171 (int *gid, int *egid, int *sgid)
getpgid 155 132 (pid_t pid) getpgid 155 132 (pid_t pid)
setfsuid 151 138 (int fsuid) setfsuid 151 138 (int fsuid)
setfsgid 152 139 (int fsgid) setfsgid 152 139 (int fsgid)
......
...@@ -54,7 +54,9 @@ __NR_readlink 89 sys_readlink (const char *path, char *buf, int bufsize) ...@@ -54,7 +54,9 @@ __NR_readlink 89 sys_readlink (const char *path, char *buf, int bufsize)
__NR_umask 95 sys_umask (int mask) __NR_umask 95 sys_umask (int mask)
__NR_getgroups 115 sys_getgroups (int gsize, unsigned int *groups) __NR_getgroups 115 sys_getgroups (int gsize, unsigned int *groups)
__NR_setresuid 117 sys_setresuid (int uid, int euid, int suid) __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_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_getpgid 121 sys_getpgid (pid_t pid)
__NR_setfsuid 122 sys_setfsuid (int fsuid) __NR_setfsuid 122 sys_setfsuid (int fsuid)
__NR_setfsgid 123 sys_setfsgid (int fsgid) __NR_setfsgid 123 sys_setfsgid (int fsgid)
......
...@@ -501,20 +501,10 @@ err: ...@@ -501,20 +501,10 @@ err:
} }
static int dump_task_creds(struct parasite_ctl *ctl, static int dump_task_creds(struct parasite_ctl *ctl,
const struct cr_imgset *fds, const struct cr_imgset *fds)
struct proc_status_creds *cr)
{ {
CredsEntry ce = CREDS_ENTRY__INIT; 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("\n");
pr_info("Dumping creds for %d)\n", ctl->pid.real); pr_info("Dumping creds for %d)\n", ctl->pid.real);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
...@@ -1475,7 +1465,6 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1475,7 +1465,6 @@ static int dump_one_task(struct pstree_item *item)
struct cr_imgset *cr_imgset = NULL; struct cr_imgset *cr_imgset = NULL;
struct parasite_drain_fd *dfds = NULL; struct parasite_drain_fd *dfds = NULL;
struct proc_posix_timers_stat proc_args; struct proc_posix_timers_stat proc_args;
struct proc_status_creds cr;
INIT_LIST_HEAD(&vmas.h); INIT_LIST_HEAD(&vmas.h);
vmas.nr = 0; vmas.nr = 0;
...@@ -1495,6 +1484,9 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1495,6 +1484,9 @@ static int dump_one_task(struct pstree_item *item)
if (ret < 0) if (ret < 0)
goto err; goto err;
if (!cr_user_is_root()) {
struct proc_status_creds cr;
ret = parse_pid_status(pid, &cr); ret = parse_pid_status(pid, &cr);
if (ret) if (ret)
goto err; goto err;
...@@ -1503,6 +1495,7 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1503,6 +1495,7 @@ static int dump_one_task(struct pstree_item *item)
pr_err("Check uid (pid: %d) failed\n", pid); pr_err("Check uid (pid: %d) failed\n", pid);
goto err; goto err;
} }
}
ret = collect_mappings(pid, &vmas); ret = collect_mappings(pid, &vmas);
if (ret) { if (ret) {
...@@ -1626,7 +1619,7 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1626,7 +1619,7 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure; goto err_cure;
} }
ret = dump_task_creds(parasite_ctl, cr_imgset, &cr); ret = dump_task_creds(parasite_ctl, cr_imgset);
if (ret) { if (ret) {
pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret); pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
goto err; goto err;
......
...@@ -29,5 +29,6 @@ struct proc_status_creds; ...@@ -29,5 +29,6 @@ struct proc_status_creds;
extern bool may_dump(struct proc_status_creds *); extern bool may_dump(struct proc_status_creds *);
struct _CredsEntry; struct _CredsEntry;
extern bool may_restore(struct _CredsEntry *); extern bool may_restore(struct _CredsEntry *);
extern bool cr_user_is_root(void);
#endif /* __CR_CRTOOLS_H__ */ #endif /* __CR_CRTOOLS_H__ */
...@@ -169,10 +169,8 @@ struct parasite_dump_misc { ...@@ -169,10 +169,8 @@ struct parasite_dump_misc {
* and still fit the struct in one page * and still fit the struct in one page
*/ */
#define PARASITE_MAX_GROUPS \ #define PARASITE_MAX_GROUPS \
(PAGE_SIZE \ (PAGE_SIZE - \
- sizeof(unsigned int) /* cap_last_cap */ \ offsetof(struct parasite_dump_creds, groups) \
- 4 * CR_CAP_SIZE * sizeof(u32) /* cap_{inh,prm,eff,bnd} */ \
- 2 * sizeof(unsigned int) /* secbits, ngroups*/ \
) / sizeof(unsigned int) /* groups */ ) / sizeof(unsigned int) /* groups */
struct parasite_dump_creds { struct parasite_dump_creds {
...@@ -183,9 +181,24 @@ struct parasite_dump_creds { ...@@ -183,9 +181,24 @@ struct parasite_dump_creds {
u32 cap_eff[CR_CAP_SIZE]; u32 cap_eff[CR_CAP_SIZE];
u32 cap_bnd[CR_CAP_SIZE]; u32 cap_bnd[CR_CAP_SIZE];
int uids[4];
int gids[4];
unsigned int secbits; unsigned int secbits;
unsigned int ngroups; unsigned int ngroups;
unsigned int groups[PARASITE_MAX_GROUPS]; /*
* FIXME -- this structure is passed to parasite code
* through parasite args area so in parasite_dump_creds()
* call we check for size of this data fits the size of
* the area. Unfortunatelly, we _actually_ use more bytes
* than the sizeof() -- we put PARASITE_MAX_GROUPS int-s
* in there, so the size check is not correct.
*
* However, all this works simply because we make sure
* the PARASITE_MAX_GROUPS is so, that the total amount
* of memory in use doesn't exceed the PAGE_SIZE and the
* args area is at least one page (PARASITE_ARG_SIZE_MIN).
*/
unsigned int groups[0];
}; };
static inline void copy_sas(ThreadSasEntry *dst, const stack_t *src) static inline void copy_sas(ThreadSasEntry *dst, const stack_t *src)
......
...@@ -762,6 +762,16 @@ int parasite_dump_creds(struct parasite_ctl *ctl, CredsEntry *ce) ...@@ -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])); BUILD_BUG_ON(sizeof(ce->groups[0]) != sizeof(pc->groups[0]));
ce->groups = pc->groups; 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; return 0;
} }
......
...@@ -236,6 +236,22 @@ static int dump_creds(struct parasite_dump_creds *args) ...@@ -236,6 +236,22 @@ static int dump_creds(struct parasite_dump_creds *args)
return -1; 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; return 0;
grps_err: grps_err:
......
...@@ -150,6 +150,11 @@ static bool check_caps(u32 *inh, u32 *eff, u32 *prm) ...@@ -150,6 +150,11 @@ static bool check_caps(u32 *inh, u32 *eff, u32 *prm)
return true; return true;
} }
bool cr_user_is_root()
{
return cr_uid == 0 && cr_gid == 0;
}
bool may_dump(struct proc_status_creds *creds) bool may_dump(struct proc_status_creds *creds)
{ {
return check_uids(creds->uids[0], creds->uids[1], creds->uids[2]) && return check_uids(creds->uids[0], creds->uids[1], creds->uids[2]) &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment