[CRIU] [PATCH] Dump capabilities from the parasite
Andrew Vagin
avagin at parallels.com
Fri Aug 15 01:22:15 PDT 2014
Hi Sophie,
On Wed, Aug 13, 2014 at 07:47:49PM -0700, Sophie Blee-Goldman wrote:
> Needed for future user namespace support. Capabilities will have to be
> dumped from the parasite, ie from inside the namespace since there is no
> obvious way to 'translate' capabilities from the global namespace (unlike
> with uids and gids, where the id mappings can be used for translation).
"capabilities" are not translated between namespaces. They can exist
only in one userns, where a process lives. If a process is created in a
new userns, it gets a full set of capabilities in this userns, and
loses all caps in a parent userns.
So if capabilities are not shown in /proc/pid/stat, we have no way to
get it except of using parasite code.
The patch looks mostly good, but I have a few comments below.
>
> Signed-off-by: Sophie Blee-Goldman <ableegoldman at google.com>
> ---
> arch/arm/syscall.def | 1 +
> arch/x86/syscall-x86-64.def | 1 +
> cr-dump.c | 17 +++--------------
> include/parasite.h | 15 +++++++++++++--
> include/prctl.h | 3 +++
> kerndat.c | 2 ++
> parasite-syscall.c | 11 +++++++++++
> pie/parasite.c | 36 +++++++++++++++++++++++++++++++++++-
> 8 files changed, 69 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arm/syscall.def b/arch/arm/syscall.def
> index c539e3e..02eaa65 100644
> --- a/arch/arm/syscall.def
> +++ b/arch/arm/syscall.def
> @@ -59,6 +59,7 @@ getpgid 155 132 (pid_t pid)
> setfsuid 151 138 (int fsuid)
> setfsgid 152 139 (int fsgid)
> getsid 156 147 (void)
> +capget 90 184 (struct cap_header *h, struct cap_data *d)
> capset 91 185 (struct cap_header *h, struct cap_data *d)
> rt_sigqueueinfo 138 178 (pid_t pid, int sig, siginfo_t *info)
> setpriority 140 97 (int which, int who, int nice)
> diff --git a/arch/x86/syscall-x86-64.def b/arch/x86/syscall-x86-64.def
> index 878cf79..ec86dfe 100644
> --- a/arch/x86/syscall-x86-64.def
> +++ b/arch/x86/syscall-x86-64.def
> @@ -59,6 +59,7 @@ __NR_getpgid 121 sys_getpgid (pid_t pid)
> __NR_setfsuid 122 sys_setfsuid (int fsuid)
> __NR_setfsgid 123 sys_setfsgid (int fsgid)
> __NR_getsid 124 sys_getsid (void)
> +__NR_capget 125 sys_capget (struct cap_header *h, struct cap_data *d)
> __NR_capset 126 sys_capset (struct cap_header *h, struct cap_data *d)
> __NR_rt_sigqueueinfo 129 sys_rt_sigqueueinfo (pid_t pid, int sig, siginfo_t *info)
> __NR_sigaltstack 131 sys_sigaltstack (const void *uss, void *uoss)
> diff --git a/cr-dump.c b/cr-dump.c
> index 1700d9d..f52af65 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -502,10 +502,6 @@ static int dump_task_creds(struct parasite_ctl *ctl,
> {
> CredsEntry ce = CREDS_ENTRY__INIT;
>
> - pr_info("\n");
> - pr_info("Dumping creds for %d)\n", ctl->pid.real);
> - pr_info("----------------------------------------\n");
> -
> ce.uid = cr->uids[0];
> ce.gid = cr->gids[0];
> ce.euid = cr->uids[1];
> @@ -515,16 +511,9 @@ static int dump_task_creds(struct parasite_ctl *ctl,
> ce.fsuid = cr->uids[3];
> ce.fsgid = cr->gids[3];
>
> - BUILD_BUG_ON(CR_CAP_SIZE != PROC_CAP_SIZE);
> -
> - ce.n_cap_inh = CR_CAP_SIZE;
> - ce.cap_inh = cr->cap_inh;
> - ce.n_cap_prm = CR_CAP_SIZE;
> - ce.cap_prm = cr->cap_prm;
> - ce.n_cap_eff = CR_CAP_SIZE;
> - ce.cap_eff = cr->cap_eff;
> - ce.n_cap_bnd = CR_CAP_SIZE;
> - ce.cap_bnd = cr->cap_bnd;
> + pr_info("\n");
> + pr_info("Dumping creds for %d)\n", ctl->pid.real);
> + pr_info("----------------------------------------\n");
>
> if (parasite_dump_creds(ctl, &ce) < 0)
> return -1;
> diff --git a/include/parasite.h b/include/parasite.h
> index af81d85..d6d243d 100644
> --- a/include/parasite.h
> +++ b/include/parasite.h
> @@ -166,10 +166,21 @@ struct parasite_dump_misc {
> * Calculate how long we can make the groups array in parasite_dump_creds
> * and still fit the struct in one page
> */
> -#define PARASITE_MAX_GROUPS \
> - ((PAGE_SIZE - 2 * sizeof(unsigned int)) / sizeof(unsigned int))
> +#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*/ \
> + ) / sizeof(unsigned int) /* groups */
>
> struct parasite_dump_creds {
> + unsigned int cap_last_cap;
> +
> + u32 cap_inh[CR_CAP_SIZE];
> + u32 cap_prm[CR_CAP_SIZE];
> + u32 cap_eff[CR_CAP_SIZE];
> + u32 cap_bnd[CR_CAP_SIZE];
> +
> unsigned int secbits;
> unsigned int ngroups;
> unsigned int groups[PARASITE_MAX_GROUPS];
Maybe we may rewrite this code like this:
struct parasite_dump_creds {
unsigned int cap_last_cap;
u32 cap_inh[CR_CAP_SIZE];
u32 cap_prm[CR_CAP_SIZE];
u32 cap_eff[CR_CAP_SIZE];
u32 cap_bnd[CR_CAP_SIZE];
unsigned int secbits;
unsigned int ngroups;
unsigned int groups[0];
};
#define PARASITE_MAX_GROUPS (PAGE_SIZE - sizeof(struct parasite_dump_creds)) /
sizeof(unsigned int)
> diff --git a/include/prctl.h b/include/prctl.h
> index b815b96..70db7b9 100644
> --- a/include/prctl.h
> +++ b/include/prctl.h
> @@ -7,6 +7,9 @@
> #ifndef PR_GET_NAME
> # define PR_GET_NAME 16
> #endif
> +#ifndef PR_CAPBSET_READ
> +# define PR_CAPBSET_READ 23
> +#endif
> #ifndef PR_CAPBSET_DROP
> # define PR_CAPBSET_DROP 24
> #endif
> diff --git a/kerndat.c b/kerndat.c
> index 0fee20b..3c87f6c 100644
> --- a/kerndat.c
> +++ b/kerndat.c
> @@ -229,6 +229,8 @@ int kerndat_init(void)
> ret = kerndat_get_dirty_track();
> if (!ret)
> ret = init_zero_page_pfn();
> + if (!ret)
> + ret = get_last_cap();
>C kerndat.o
kerndat.c: In function ‘kerndat_init’:
kerndat.c:221:3: error: implicit declaration of function ‘get_last_cap’
[-Werror=implicit-function-declaration]
ret = get_last_cap();
^
cc1: all warnings being treated as errors
> return ret;
> }
Thanks,
Andrew
More information about the CRIU
mailing list