[CRIU] [PATCH] Dump capabilities from the parasite

Andrew Vagin avagin at parallels.com
Fri Aug 15 02:59:55 PDT 2014


On Fri, Aug 15, 2014 at 12:22:15PM +0400, Andrew Vagin wrote:
> 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.

It's obvious how to fix the last comment. All other comments are cosmetic.

Acked-by: Andrew Vagin <avagin at parallels.com>

> 
> > 
> > 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
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list