[CRIU] [PATCH 8/9] creds: restore -- Implement per-thread restore of credentials
Cyrill Gorcunov
gorcunov at gmail.com
Fri Dec 18 09:53:58 PST 2015
On Fri, Dec 18, 2015 at 05:14:34PM +0300, Pavel Emelyanov wrote:
...
> > +static struct thread_creds_args *
> > +rst_prep_creds_args(struct thread_creds_args *prev, CredsEntry *ce)
> > +{
> > + unsigned long this_pos = rst_mem_cpos(RM_PRIVATE);
> > + struct thread_creds_args *args;
> > +
> > + if (!verify_cap_size(ce)) {
> > + pr_err("Caps size mismatch %d %d %d %d\n",
> > + (int)ce->n_cap_inh, (int)ce->n_cap_eff,
> > + (int)ce->n_cap_prm, (int)ce->n_cap_bnd);
> > + return ERR_PTR(-EINVAL);
> > + }
> > +
> > + if (!may_restore(ce))
> > + return ERR_PTR(-EINVAL);
> > +
> > + args = rst_mem_alloc(sizeof(*args), RM_PRIVATE);
> > + if (!args)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + args->cap_last_cap = kdat.last_cap;
>
> This is per-thread constant, leave it on task_args.
What for? I use this variable inside pie/restorer, where arguments
are only _thread_ data, not task, so I need a copy here. Sure I can
add some references to access this variable from task args but I think
it makes code even more vague.
...
> > +static int rst_prep_creds(pid_t pid, CoreEntry *core, unsigned long *creds_pos)
> > +{
> > + size_t i;
> > +
> > + /*
> > + * This is _really_ very old image
> > + * format where @thread_core were not
> > + * present. It means we don't have
> > + * creds either, just ignore and exit
> > + * early.
> > + */
> > + if (unlikely(!core->thread_core)) {
> > + *creds_pos = 0;
> > + return 0;
> > + }
> > +
> > + *creds_pos = rst_mem_cpos(RM_PRIVATE);
> > +
> > + /*
> > + * Old format: one Creds per task carried in own image file.
> > + */
> > + if (!core->thread_core->creds)
> > + return rst_prep_creds_from_img(pid);
>
> This would produce only one creds object at creds_cpos, while the loop
> below would produce several of them. But the threads_args code ... more
> below scans (should scan) creds_pos as array which would only work for
> "new" case.
Yes, for legacy case we create one object which get used for task only,
the ->next field always null. Note the legacy case gonna be out of
date pretty soon so consider it rather as exception than a regular
basis.
> > +
> > + for (i = 0; i < current->nr_threads; i++) {
> > + CredsEntry *ce = current->core[i]->thread_core->creds;
> > + struct thread_creds_args *args = NULL;
> > +
> > + args = rst_prep_creds_args(args, ce);
>
> The args as a function argument is always NULL here, so it is in the legacy
> function above. Is this intended behavior?
Nope, just non refreshed sources, thanks! I'll update.
> > @@ -3157,6 +3218,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
> > thread_args[i].clear_tid_addr = CORE_THREAD_ARCH_INFO(tcore)->clear_tid_addr;
> > core_get_tls(tcore, &thread_args[i].tls);
> >
> > + rst_reloc_creds(&thread_args[i], &creds_pos_next);
>
> The creds_pos_next is write-only constant variable here. Why do threads get
> different creds after all?
Same here, forgot to refresh. I'm preparing new bundle now.
> > +
> > if (tcore->thread_core) {
> > thread_args[i].has_futex = true;
> > thread_args[i].futex_rla = tcore->thread_core->futex_rla;
>
> > @@ -884,7 +895,7 @@ long __export_restore_task(struct task_restore_args *args)
> > log_set_fd(args->logfd);
> > log_set_loglevel(args->loglevel);
> >
> > - cap_last_cap = args->cap_last_cap;
> > + cap_last_cap = args->t->creds_args->cap_last_cap;
>
> The global cap_last_cap becomes unused after this patch.
Yes, thanks, dropped.
More information about the CRIU
mailing list