: [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