: [CRIU] [PATCH] restorer: Make sure the protection on code/data mm areas do fit the kernel requirements

Kir Kolyshkin kir at openvz.org
Fri Apr 13 04:34:39 EDT 2012


13.04.2012 11:47 пользователь "Cyrill Gorcunov" <gorcunov at openvz.org>
написал:
>
> Otherwise the restore procedure might refuse to continue.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  restorer.c |   66
+++++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 54 insertions(+), 12 deletions(-)
>
> diff --git a/restorer.c b/restorer.c
> index 0160108..f4ea6f8 100644
> --- a/restorer.c
> +++ b/restorer.c
> @@ -244,7 +244,56 @@ static long restore_self_exe_late(struct
task_restore_core_args *args)
>        return 0;
>  }
>
> -static u64 restore_mapping(const struct vma_entry *vma_entry)
> +/*
> + * The kernel applies special requirements for code/data protection,
> + * thus we setup the flags needed here.
> + *
> + * Note, this imples the caller code will restore the original

implies

> + * protection later. Also for code section the write flag is cleared,
> + * so make sure you already uploaded page contents if needed.
> + */
> +static int setup_mm_special(struct task_restore_core_args *args,
> +                           const struct vma_entry *vma_entry)
> +{
> +       int flags = vma_entry->flags;
> +       int ret = 0;
> +
> +       if (vma_entry->start == (long)args->mm.mm_start_code ||
> +           vma_entry->end == (long)args->mm.mm_end_code) {
> +               flags |= PROT_EXEC | PROT_READ;
> +               flags &= ~PROT_WRITE;
> +
> +               sys_mprotect(vma_entry->start,
> +                            vma_entry_len(vma_entry),
> +                            flags);
> +
> +               if (vma_entry->start == (long)args->mm.mm_start_code)
> +                       ret |= sys_prctl_safe(PR_SET_MM,
PR_SET_MM_START_CODE,
> +
(long)args->mm.mm_start_code, 0);
> +               else
> +                       ret |= sys_prctl_safe(PR_SET_MM,
PR_SET_MM_END_CODE,
> +                                             (long)args->mm.mm_end_code,
0);
> +
> +       }
> +
> +       if (vma_entry->start == (long)args->mm.mm_start_data ||
> +               vma_entry->end == (long)args->mm.mm_end_data) {
> +               flags |= PROT_READ | PROT_WRITE;
> +               flags &= ~PROT_EXEC;
> +
> +               if (vma_entry->start == (long)args->mm.mm_start_data)
> +                       ret |= sys_prctl_safe(PR_SET_MM,
PR_SET_MM_START_DATA,
> +
(long)args->mm.mm_start_data, 0);
> +               else
> +                       ret |= sys_prctl_safe(PR_SET_MM,
PR_SET_MM_END_DATA,
> +                                             (long)args->mm.mm_end_data,
0);
> +       }
> +
> +       return ret;
> +}
> +
> +static u64 restore_mapping(struct task_restore_core_args *args,
> +                          const struct vma_entry *vma_entry)
>  {
>        int prot        = vma_entry->prot;
>        int flags       = vma_entry->flags | MAP_FIXED;
> @@ -346,7 +395,7 @@ long restore_task(struct task_restore_core_args *args)
>                if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
>                        continue;
>
> -               va = restore_mapping(vma_entry);
> +               va = restore_mapping(args, vma_entry);
>
>                if (va != vma_entry->start) {
>                        write_num_n(__LINE__);
> @@ -386,8 +435,8 @@ long restore_task(struct task_restore_core_args *args)
>        sys_close(args->fd_pages);
>
>        /*
> -        * Walk though all VMAs again to drop PROT_WRITE
> -        * if it was not there.
> +        * Walk though all VMAs again to restore
> +        * original protection.
>         */
>        for (vma_entry = args->tgt_vmas; vma_entry->start != 0;
vma_entry++) {
>                if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR)))
> @@ -403,9 +452,7 @@ long restore_task(struct task_restore_core_args *args)
>                                futex_set_and_wake(&entry->lock, 1);
>                }
>
> -               if (vma_entry->prot & PROT_WRITE)
> -                       continue;
> -
> +               setup_mm_special(args, vma_entry);
>                sys_mprotect(vma_entry->start,
>                             vma_entry_len(vma_entry),
>                             vma_entry->prot);
> @@ -428,11 +475,6 @@ long restore_task(struct task_restore_core_args
*args)
>         * Tune up the task fields.
>         */
>        ret |= sys_prctl_safe(PR_SET_NAME, (long)core_entry->tc.comm, 0,
0);
> -
> -       ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE,
 (long)args->mm.mm_start_code, 0);
> -       ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE,
 (long)args->mm.mm_end_code, 0);
> -       ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_DATA,
 (long)args->mm.mm_start_data, 0);
> -       ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_DATA,
 (long)args->mm.mm_end_data, 0);
>        ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_STACK,
(long)args->mm.mm_start_stack, 0);
>        ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_BRK,
(long)args->mm.mm_start_brk, 0);
>        ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_BRK,
(long)args->mm.mm_brk, 0);
> --
> 1.7.7.6
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://openvz.org/mailman/listinfo/criu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://openvz.org/pipermail/criu/attachments/20120413/ff6dbdf6/attachment.html


More information about the CRIU mailing list