[CRIU] [PATCH 20/23] ptrace.c: don't seize the task that doesn't run in the userspace

Alexander Kartashov alekskartashov at parallels.com
Mon Jan 14 02:20:14 EST 2013


If a task executes a non-userspace code (that sometimes takes place on ARM)
while being seized the subsequent infection with the syscall blob fails
because the VMA the PC is in is surely shouldn't be written.

The patch modifies the function seize_task() to check the PC of the task
being seized is below the TASK_SIZE boundary. If the check fails
another seizure attempt is made in 2 sec.
---
 ptrace.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/ptrace.c b/ptrace.c
index 0140918..67b499a 100644
--- a/ptrace.c
+++ b/ptrace.c
@@ -50,6 +50,7 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
 	int status;
 	int ret, ret2;
 	struct proc_pid_stat_small ps;
+	user_regs_struct_t regs;
 
 	ret = ptrace(PTRACE_SEIZE, pid, NULL, 0);
 
@@ -129,6 +130,23 @@ try_again:
 		goto try_again;
 	}
 
+	if (ptrace(PTRACE_GETREGS, pid, NULL, &regs)) {
+		pr_perror("SEIZE %d: failed to get the task registers.", pid);
+		goto err;
+	}
+
+	if (REG_IP(regs) >= TASK_SIZE) {
+		pr_info("SEIZE %d: the current PC is outside the user virtual address space; retrying to seize in 2 sec.\n", pid);
+
+		if (ptrace(PTRACE_CONT, pid, NULL, NULL)) {
+			pr_perror("SEIZE %d: can't continue on a seize retry.", pid);
+			goto err;
+		}
+
+		sleep(2);
+		goto try_again;
+	}
+
 	if (si.si_signo == SIGTRAP)
 		return TASK_ALIVE;
 	else if (si.si_signo == SIGSTOP)
-- 
1.7.10.4



More information about the CRIU mailing list