[CRIU] [PATCH 3/5] vdso: Proxify vDSO code on restore

Pavel Emelyanov xemul at parallels.com
Mon May 20 07:54:56 EDT 2013


On 05/16/2013 07:33 PM, Cyrill Gorcunov wrote:
> 
> When tasks are restored in a kernel which version differ from the one
> they were being dumped on, the vDSO content may has been changed thus
> any call to vDSO service routine will lead to SIGBUS in a better case
> or in wrong results without notice in a worst one.
> 
> So to work this situation out we need a that named vDSO proxy, where
> any call to original vDSO service routine shall be redirected to
> a valid runtime vDSO supplied by the kernel we're restoring on.
> 
> In terms of ugly ascii gprahics it might be represented as following.
> 
> Original vDSO in image
> ======================
> 
>     +---------------------------+
>     | __vdso_getcpu             |
>     |       ...                 |
>     |       function body here  |
>     +---------------------------+
>     | __vdso_time               |
>     |       ...                 |
>     |       function body here  |
>     +---------------------------+
>     ...
> 
> Run-time proxified calls
> ========================
> 
>     Mapped from image and then patched
> 
>     +---------------------------+
>     | __vdso_getcpu             |
>     |       redirect            +----+
>     |       int3                |    |
>     +---------------------------+    |
>     | __vdso_time               |    |
>     |       redirect            +-+  |
>     |       int3                | |  |
>     +---------------------------+ |  |
>     ...                           |  |
>                                   |  |  New memory area with valid vDSO content
>                                   |  |  +---------------------------+
>                                   |  |  | __vdso_getcpu             |
>                                   |  +->|       ...                 |
>                                   |     |       function body here  |
>                                   |     +---------------------------+
>                                   |     | __vdso_time               |
>                                   +---->|       ...                 |
>                                         |       function body here  |
>                                         +---------------------------+
>                                         ...
> 
> To achieve this we
> 
>  1) Read vDSO from memory the kernel provides us and remember
>     its structure and functions addresses.
> 
>  2) Analyze VMAs read from images, if vdso is met -- remember where
>     this area is premaped.
> 
>  3) Once the vdso page data read from disk -- parse it and fill symbols
>     table, we will use it to patch the vdso calls. Then mark it with
>     special vdso signature. Thus on next dump session it might be
>     recognized as vdso area.
> 
>  4) When we start unmapping self vmas, if runtime vdso met (from [1])
>     we remap it at some new place.
> 
>  5) Patch old vDSO entry points to redirect calls to new vDSO entries.
> 
>  6) Mark new vDSO with special sign thus in future patch the dumper will
>     find that the second vDSO should be omitted from writting on disk.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  cr-restore.c       | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  include/restorer.h | 12 ++++++++
>  pie/restorer.c     | 54 ++++++++++++++++++++++++++++++++++
>  3 files changed, 148 insertions(+), 3 deletions(-)
> 


> @@ -263,6 +268,18 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
>  	if (vma_entry_is(&vma->vma, VMA_FILE_PRIVATE))
>  		close(vma->vma.fd);
>  
> +	if (vma_entry_is(&vma->vma, VMA_AREA_VDSO)) {
> +		if (vdso_proxy.proxify) {
> +			pr_err("Got second vDSO area while only one expected\n");
> +			return -1;
> +		}
> +
> +		vdso_proxy.sym_dumpee.vma_start = vma->vma.start;
> +		vdso_proxy.sym_dumpee.vma_end = vma->vma.end;
> +		vdso_proxy.premmaped_at = (unsigned long)addr;
> +		vdso_proxy.proxify = true;
> +	}
> +
>  	return 0;
>  }

So you _always_ put VDSO proxy. I thought we've decided not to do it if
symbols offsets match.



More information about the CRIU mailing list