[CRIU] [crtools-bot for Pavel Emelyanov ] restorer: Fix bootstrap allocation

Cyrill Gorcunov gorcunov at openvz.org
Fri Mar 2 12:31:35 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit e94c85fe6e91058349fbca65ad8e9d278bf8e938
Author: Pavel Emelyanov <xemul at parallels.com>
Date:   Fri Mar 2 19:28:13 2012 +0400

    restorer: Fix bootstrap allocation
    
    There are three bugs in this code.
    
    1. self vmas list is released before get-hint is called
    2. get-hint code wrongly detects the hole (just bugs, no details)
    3. exec hint is mapped without MAP_FIXED, but should
    
    Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c |   44 +++++++++++++++++++++++++++-----------------
 1 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 5c164fd..11c2c46 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1512,16 +1512,27 @@ static long restorer_get_vma_hint(pid_t pid, struct list_head *self_vma_list, lo
 		}
 
 		if ((vma.start - prev_vma_end) > vma_len) {
+			unsigned long prev_vma_end2 = 0;
+
 			list_for_each_entry(vma_area, self_vma_list, list) {
-				if (vma_area->vma.start <= prev_vma_end &&
-				    vma_area->vma.end >= prev_vma_end)
-					break;
+				if (!prev_vma_end2) {
+					prev_vma_end2 = vma_area->vma.end;
+					continue;
+				}
+
+				if ((prev_vma_end2 >= prev_vma_end2) &&
+						(vma_area->vma.start - prev_vma_end2) > vma_len) {
+					hint = prev_vma_end2;
+					goto found;
+				}
+
+				prev_vma_end2 = vma_area->vma.end;
 			}
-			hint = prev_vma_end;
-			break;
-		} else
-			prev_vma_end = vma.end;
+		}
+
+		prev_vma_end = vma.end;
 	}
+found:
 	close_safe(&fd);
 	return hint;
 }
@@ -1700,8 +1711,6 @@ static void sigreturn_restore(pid_t pid)
 		num++;
 	}
 
-	free_mappings(&self_vma_list);
-
 	restore_code_len	= sizeof(restorer_blob);
 	restore_code_len	= round_up(restore_code_len, 16);
 
@@ -1735,18 +1744,19 @@ static void sigreturn_restore(pid_t pid)
 		pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
 		       restore_task_vma_len + restore_thread_vma_len);
 		goto err;
-	} else {
-		pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n",
-			exec_mem_hint,
-			KBYTES(restore_task_vma_len + restore_thread_vma_len));
 	}
 
+	pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n", exec_mem_hint,
+			KBYTES(restore_task_vma_len + restore_thread_vma_len));
+
+	free_mappings(&self_vma_list);
+
 	/* VMA we need to run task_restore code */
 	exec_mem = mmap((void *)exec_mem_hint,
 			restore_task_vma_len + restore_thread_vma_len,
 			PROT_READ | PROT_WRITE | PROT_EXEC,
-			MAP_PRIVATE | MAP_ANON, 0, 0);
-	if (exec_mem == MAP_FAILED) {
+			MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
+	if (exec_mem != (void *)exec_mem_hint) {
 		pr_err("Can't mmap section for restore code\n");
 		goto err;
 	}
@@ -1784,7 +1794,7 @@ static void sigreturn_restore(pid_t pid)
 	 * but this area is taken into account for 'hint' memory
 	 * address.
 	 */
-	shmems_ref = (struct shmems *)(exec_mem_hint +
+	shmems_ref = (struct shmems *)(exec_mem +
 				       restore_task_vma_len +
 				       restore_thread_vma_len);
 	ret = shmem_remap(shmems, shmems_ref, SHMEMS_SIZE);
@@ -1792,7 +1802,7 @@ static void sigreturn_restore(pid_t pid)
 		goto err;
 	task_args->shmems	= shmems_ref;
 
-	shmems_ref = (struct shmems *)(exec_mem_hint +
+	shmems_ref = (struct shmems *)(exec_mem +
 				       restore_task_vma_len +
 				       restore_thread_vma_len +
 				       SHMEMS_SIZE);


More information about the CRIU mailing list