Branch data Line data Source code
1 : : #include <stdio.h>
2 : : #include <stdlib.h>
3 : : #include <signal.h>
4 : : #include <limits.h>
5 : : #include <unistd.h>
6 : : #include <errno.h>
7 : : #include <dirent.h>
8 : : #include <string.h>
9 : :
10 : : #include <fcntl.h>
11 : : #include <grp.h>
12 : :
13 : : #include <sys/types.h>
14 : : #include <sys/stat.h>
15 : : #include <sys/mman.h>
16 : : #include <sys/vfs.h>
17 : : #include <sys/ptrace.h>
18 : : #include <sys/wait.h>
19 : : #include <sys/file.h>
20 : : #include <sys/shm.h>
21 : : #include <sys/mount.h>
22 : :
23 : : #include <sched.h>
24 : :
25 : : #include <sys/sendfile.h>
26 : :
27 : : #include "compiler.h"
28 : : #include "types.h"
29 : :
30 : : #include "image.h"
31 : : #include "util.h"
32 : : #include "log.h"
33 : : #include "syscall.h"
34 : : #include "restorer.h"
35 : : #include "sockets.h"
36 : : #include "sk-packet.h"
37 : : #include "lock.h"
38 : : #include "files.h"
39 : : #include "files-reg.h"
40 : : #include "pipes.h"
41 : : #include "fifo.h"
42 : : #include "sk-inet.h"
43 : : #include "eventfd.h"
44 : : #include "eventpoll.h"
45 : : #include "signalfd.h"
46 : : #include "proc_parse.h"
47 : : #include "restorer-blob.h"
48 : : #include "crtools.h"
49 : : #include "namespaces.h"
50 : : #include "shmem.h"
51 : : #include "mount.h"
52 : : #include "inotify.h"
53 : : #include "pstree.h"
54 : : #include "net.h"
55 : : #include "tty.h"
56 : : #include "cpu.h"
57 : : #include "fpu.h"
58 : :
59 : : #include "protobuf.h"
60 : : #include "protobuf/sa.pb-c.h"
61 : : #include "protobuf/itimer.pb-c.h"
62 : : #include "protobuf/vma.pb-c.h"
63 : :
64 : : static struct pstree_item *current;
65 : :
66 : : static int restore_task_with_children(void *);
67 : : static int sigreturn_restore(pid_t pid, CoreEntry *core);
68 : : static int prepare_restorer_blob(void);
69 : :
70 : : static LIST_HEAD(rst_vma_list);
71 : : static int rst_nr_vmas;
72 : :
73 : 698 : static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
74 : : {
75 : : void *ret;
76 : :
77 : 698 : ret = mremap(old_addr, size, size,
78 : : MREMAP_FIXED | MREMAP_MAYMOVE, new_addr);
79 [ - + ]: 698 : if (new_addr != ret) {
80 : 0 : pr_perror("mremap failed");
81 : 698 : return -1;
82 : : }
83 : :
84 : : return 0;
85 : : }
86 : :
87 : 380 : static int crtools_prepare_shared(void)
88 : : {
89 [ + - ]: 380 : if (prepare_shared_fdinfo())
90 : : return -1;
91 : :
92 : : /* Connections are unlocked from crtools */
93 [ + - ]: 380 : if (collect_inet_sockets())
94 : : return -1;
95 : :
96 [ + - ]: 380 : if (tty_prep_fds())
97 : : return -1;
98 : :
99 : 380 : return 0;
100 : : }
101 : :
102 : 355 : static int root_prepare_shared(void)
103 : : {
104 : 355 : int ret = 0;
105 : : struct pstree_item *pi;
106 : :
107 : 355 : pr_info("Preparing info about shared resources\n");
108 : :
109 [ + - ]: 355 : if (prepare_shmem_restore())
110 : : return -1;
111 : :
112 [ + - ]: 355 : if (prepare_shared_tty())
113 : : return -1;
114 : :
115 [ + - ]: 355 : if (prepare_shared_reg_files())
116 : : return -1;
117 : :
118 [ + - ]: 355 : if (collect_reg_files())
119 : : return -1;
120 : :
121 [ + - ]: 355 : if (collect_pipes())
122 : : return -1;
123 : :
124 [ + - ]: 355 : if (collect_fifo())
125 : : return -1;
126 : :
127 [ + - ]: 355 : if (collect_unix_sockets())
128 : : return -1;
129 : :
130 [ + - ]: 355 : if (collect_packet_sockets())
131 : : return -1;
132 : :
133 [ + - ]: 355 : if (collect_eventfd())
134 : : return -1;
135 : :
136 [ + - ]: 355 : if (collect_eventpoll())
137 : : return -1;
138 : :
139 [ + - ]: 355 : if (collect_signalfd())
140 : : return -1;
141 : :
142 [ + - ]: 355 : if (collect_inotify())
143 : : return -1;
144 : :
145 [ + - ]: 355 : if (collect_tty())
146 : : return -1;
147 : :
148 [ + + ]: 1878 : for_each_pstree_item(pi) {
149 [ + + ]: 1523 : if (pi->state == TASK_HELPER)
150 : 64 : continue;
151 : :
152 : 1459 : ret = prepare_shmem_pid(pi->pid.virt);
153 [ + - ]: 1459 : if (ret < 0)
154 : : break;
155 : :
156 : 1459 : ret = prepare_fd_pid(pi->pid.virt, pi->rst);
157 [ + - ]: 1459 : if (ret < 0)
158 : : break;
159 : : }
160 : :
161 [ + - ]: 355 : if (ret < 0)
162 : : goto err;
163 : :
164 : 355 : mark_pipe_master();
165 : :
166 : 355 : ret = tty_setup_slavery();
167 [ + - ]: 355 : if (ret)
168 : : goto err;
169 : :
170 : 355 : ret = resolve_unix_peers();
171 [ + - ]: 355 : if (ret)
172 : : goto err;
173 : :
174 : 355 : ret = prepare_restorer_blob();
175 [ + - ]: 355 : if (ret)
176 : : goto err;
177 : :
178 : 355 : show_saved_shmems();
179 : 355 : show_saved_files();
180 : : err:
181 : 355 : return ret;
182 : : }
183 : :
184 : : /* Map a private vma, if it is not mapped by a parrent yet */
185 : 9667 : static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
186 : : struct vma_area **pvma, struct list_head *pvma_list)
187 : : {
188 : : int ret;
189 : 9667 : void *addr, *paddr = NULL;
190 : : unsigned long nr_pages;
191 : 9667 : struct vma_area *p = *pvma;
192 : :
193 [ + + ]: 9667 : if (vma_entry_is(&vma->vma, VMA_FILE_PRIVATE)) {
194 : 5716 : ret = get_filemap_fd(pid, &vma->vma);
195 [ - + ]: 5716 : if (ret < 0) {
196 : 0 : pr_err("Can't fixup fd\n");
197 : 0 : return -1;
198 : : }
199 : 5716 : vma->vma.fd = ret;
200 : : /* shmid will be used for a temporary address */
201 : 5716 : vma->vma.shmid = 0;
202 : : }
203 : :
204 : 9667 : nr_pages = vma_entry_len(&vma->vma) / PAGE_SIZE;
205 [ - + ]: 9667 : vma->page_bitmap = xzalloc(BITS_TO_LONGS(nr_pages) * sizeof(long));
206 [ + - ]: 9667 : if (vma->page_bitmap == NULL)
207 : : return -1;
208 : :
209 [ + + ]: 12087 : list_for_each_entry_continue(p, pvma_list, list) {
210 [ + + ]: 6316 : if (p->vma.start > vma->vma.start)
211 : : break;
212 : :
213 [ + + ][ + + ]: 4397 : if (p->vma.end == vma->vma.end &&
214 : : p->vma.start == vma->vma.start) {
215 : 1977 : pr_info("COW 0x%016lx-0x%016lx 0x%016lx vma\n",
216 : : vma->vma.start, vma->vma.end, vma->vma.pgoff);
217 : 1977 : paddr = (void *) vma_premmaped_start(&p->vma);
218 : 1977 : break;
219 : : }
220 : :
221 : : }
222 : :
223 : 9667 : *pvma = p;
224 : :
225 [ + + ]: 9667 : if (paddr == NULL) {
226 : 7690 : pr_info("Map 0x%016lx-0x%016lx 0x%016lx vma\n",
227 : : vma->vma.start, vma->vma.end, vma->vma.pgoff);
228 : :
229 : 7690 : addr = mmap(tgt_addr, vma_entry_len(&vma->vma),
230 : 7690 : vma->vma.prot | PROT_WRITE,
231 : 7690 : vma->vma.flags | MAP_FIXED,
232 : 15380 : vma->vma.fd, vma->vma.pgoff);
233 : :
234 [ - + ]: 7690 : if (addr == MAP_FAILED) {
235 : 0 : pr_perror("Unable to map ANON_VMA");
236 : 0 : return -1;
237 : : }
238 : : } else {
239 : 1977 : vma->ppage_bitmap = p->page_bitmap;
240 : :
241 : 1977 : addr = mremap(paddr, vma_area_len(vma), vma_area_len(vma),
242 : : MREMAP_FIXED | MREMAP_MAYMOVE, tgt_addr);
243 [ - + ]: 1977 : if (addr != tgt_addr) {
244 : 0 : pr_perror("Unable to remap a private vma");
245 : 0 : return -1;
246 : : }
247 : :
248 : : }
249 : :
250 : 9667 : vma_premmaped_start(&(vma->vma)) = (unsigned long) addr;
251 : :
252 [ + + ]: 9667 : if (vma_entry_is(&vma->vma, VMA_FILE_PRIVATE))
253 : 9667 : close(vma->vma.fd);
254 : :
255 : : return 0;
256 : : }
257 : :
258 : 614 : static int restore_priv_vma_content(pid_t pid)
259 : : {
260 : : struct vma_area *vma;
261 : 614 : int fd, ret = 0;
262 : :
263 : 614 : unsigned int nr_restored = 0;
264 : 614 : unsigned int nr_shared = 0;
265 : 614 : unsigned int nr_droped = 0;
266 : :
267 : 614 : vma = list_first_entry(&rst_vma_list, struct vma_area, list);
268 : :
269 : 614 : fd = open_image_ro(CR_FD_PAGES, pid);
270 [ + - ]: 24019 : if (fd < 0)
271 : : return -1;
272 : :
273 : : /*
274 : : * Read page contents.
275 : : */
276 : : while (1) {
277 : : u64 va, page_offset;
278 : : char buf[PAGE_SIZE];
279 : : void *p;
280 : :
281 : 24019 : ret = read(fd, &va, sizeof(va));
282 [ + + ]: 24019 : if (!ret)
283 : : break;
284 : :
285 [ - + ]: 23405 : if (ret != sizeof(va)) {
286 : 0 : pr_err("Bad mapping page size %d\n", ret);
287 : : return -1;
288 : : }
289 : :
290 [ - + ]: 23405 : BUG_ON(va < vma->vma.start);
291 : :
292 [ + + ]: 32561 : while (va >= vma->vma.end) {
293 [ - + ]: 9156 : BUG_ON(vma->list.next == &rst_vma_list);
294 : 9156 : vma = list_entry(vma->list.next, struct vma_area, list);
295 : : }
296 : :
297 : 23405 : page_offset = (va - vma->vma.start) / PAGE_SIZE;
298 : :
299 : 23405 : set_bit(page_offset, vma->page_bitmap);
300 [ + + ]: 23405 : if (vma->ppage_bitmap)
301 : 4200 : clear_bit(page_offset, vma->ppage_bitmap);
302 : :
303 : 23405 : ret = read(fd, buf, PAGE_SIZE);
304 [ - + ]: 23405 : if (ret != PAGE_SIZE) {
305 : 0 : pr_err("Can'r read mapping page %d\n", ret);
306 : : return -1;
307 : : }
308 : :
309 : 46810 : p = (void *) (va - vma->vma.start +
310 : 23405 : vma_premmaped_start(&vma->vma));
311 [ + + ]: 23405 : if (memcmp(p, buf, PAGE_SIZE) == 0) {
312 : 3963 : nr_shared++;
313 : 3963 : continue;
314 : : }
315 : :
316 : 19442 : memcpy(p, buf, PAGE_SIZE);
317 : 19442 : nr_restored++;
318 : : }
319 : 614 : close(fd);
320 : :
321 : : /* Remove pages, which were not shared with a child */
322 [ + + ]: 10998 : list_for_each_entry(vma, &rst_vma_list, list) {
323 : 10384 : unsigned long size, i = 0;
324 : 10384 : void *addr = (void *) vma_premmaped_start(&vma->vma);
325 : :
326 [ + + ]: 10384 : if (vma->ppage_bitmap == NULL)
327 : 8407 : continue;
328 : :
329 : 1977 : size = vma_entry_len(&vma->vma) / PAGE_SIZE;
330 : : while (1) {
331 : : /* Find all pages, which are not shared with this child */
332 : 3630 : i = find_next_bit(vma->ppage_bitmap, size, i);
333 : :
334 [ + + ]: 3630 : if ( i >= size)
335 : : break;
336 : :
337 : 1653 : ret = madvise(addr + PAGE_SIZE * i,
338 : : PAGE_SIZE, MADV_DONTNEED);
339 [ - + ]: 1653 : if (ret < 0) {
340 : 0 : pr_perror("madvise failed\n");
341 : 0 : return -1;
342 : : }
343 : 1653 : i++;
344 : 1653 : nr_droped++;
345 : 1653 : }
346 : : }
347 : :
348 : 614 : pr_info("nr_restored_pages: %d\n", nr_restored);
349 : 614 : pr_info("nr_shared_pages: %d\n", nr_shared);
350 : 614 : pr_info("nr_droped_pages: %d\n", nr_droped);
351 : :
352 : 614 : return 0;
353 : : }
354 : :
355 : 624 : static int read_vmas(int pid)
356 : : {
357 : 624 : int fd, ret = 0;
358 : 624 : LIST_HEAD(old);
359 : : struct vma_area *pvma, *vma;
360 : 624 : unsigned long priv_size = 0;
361 : : void *addr;
362 : :
363 : 624 : void *old_premmapped_addr = NULL;
364 : 624 : unsigned long old_premmapped_len, pstart = 0;
365 : :
366 : 624 : rst_nr_vmas = 0;
367 : : list_replace_init(&rst_vma_list, &old);
368 : :
369 : : /* Skip errors, because a zombie doesn't have an image of vmas */
370 : 624 : fd = open_image_ro(CR_FD_VMAS, pid);
371 [ + + ]: 624 : if (fd < 0) {
372 [ - + ]: 10 : if (errno != ENOENT)
373 : 11008 : ret = fd;
374 : : goto out;
375 : : }
376 : :
377 : : while (1) {
378 : : struct vma_area *vma;
379 : : VmaEntry *e;
380 : :
381 : 10998 : ret = -1;
382 [ - + ][ + - ]: 10998 : vma = alloc_vma_area();
383 [ + - ]: 10998 : if (!vma)
384 : : break;
385 : :
386 : 10998 : ret = pb_read_one_eof(fd, &e, PB_VMAS);
387 [ + + ]: 10998 : if (ret <= 0)
388 : : break;
389 : :
390 : 10384 : rst_nr_vmas++;
391 : 10384 : list_add_tail(&vma->list, &rst_vma_list);
392 : :
393 [ - + ]: 10384 : if (e->fd != -1) {
394 : 0 : ret = -1;
395 : 0 : pr_err("Error in vma->fd setting (%Ld)\n",
396 : : (unsigned long long)e->fd);
397 : : break;
398 : : }
399 : :
400 : 10384 : vma->vma = *e;
401 : 10384 : vma_entry__free_unpacked(e, NULL);
402 : :
403 [ + + ][ + + ]: 10384 : if (!vma_priv(&vma->vma))
404 : 717 : continue;
405 : :
406 : 9667 : priv_size += vma_area_len(vma);
407 : : }
408 : :
409 : : /* Reserve a place for mapping private vma-s one by one */
410 : 614 : addr = mmap(NULL, priv_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
411 [ - + ]: 614 : if (addr == MAP_FAILED) {
412 : 0 : pr_perror("Unable to reserve memory");
413 : : return -1;
414 : : }
415 : :
416 : 614 : old_premmapped_addr = current->rst->premmapped_addr;
417 : 614 : old_premmapped_len = current->rst->premmapped_len;
418 : 614 : current->rst->premmapped_addr = addr;
419 : 614 : current->rst->premmapped_len = priv_size;
420 : :
421 : 614 : pvma = list_entry(&old, struct vma_area, list);
422 : :
423 [ + + ]: 10998 : list_for_each_entry(vma, &rst_vma_list, list) {
424 [ - + ]: 10384 : if (pstart > vma->vma.start) {
425 : 0 : ret = -1;
426 : 0 : pr_err("VMA-s are not sorted in the image file\n");
427 : 0 : break;
428 : : }
429 : 10384 : pstart = vma->vma.start;
430 : :
431 [ + + ][ + + ]: 10384 : if (!vma_priv(&vma->vma))
432 : 717 : continue;
433 : :
434 : 9667 : ret = map_private_vma(pid, vma, addr, &pvma, &old);
435 [ + - ]: 9667 : if (ret < 0)
436 : : break;
437 : :
438 : 9667 : addr += vma_area_len(vma);
439 : : }
440 : :
441 [ + - ]: 614 : if (ret == 0)
442 : 614 : ret = restore_priv_vma_content(pid);
443 : 614 : close(fd);
444 : :
445 : : out:
446 [ + + ]: 4953 : while (!list_empty(&old)) {
447 : 4329 : vma = list_first_entry(&old, struct vma_area, list);
448 : 4329 : list_del(&vma->list);
449 [ + - ]: 4953 : xfree(vma);
450 : : }
451 : :
452 [ - + # # ]: 624 : if (old_premmapped_addr &&
453 : 0 : munmap(old_premmapped_addr, old_premmapped_len)) {
454 : 624 : pr_perror("Unable to unmap %p(%lx)",
455 : : old_premmapped_addr, old_premmapped_len);
456 : : return -1;
457 : : }
458 : :
459 : :
460 : : return ret;
461 : : }
462 : :
463 : 349 : static int open_vmas(int pid)
464 : : {
465 : : struct vma_area *vma;
466 : 349 : int ret = 0;
467 : :
468 [ + + ]: 6404 : list_for_each_entry(vma, &rst_vma_list, list) {
469 [ + + ]: 6055 : if (!(vma_entry_is(&vma->vma, VMA_AREA_REGULAR)))
470 : 349 : continue;
471 : :
472 : 5706 : pr_info("Opening 0x%016lx-0x%016lx 0x%016lx (%x) vma\n",
473 : : vma->vma.start, vma->vma.end,
474 : : vma->vma.pgoff, vma->vma.status);
475 : :
476 [ + + ]: 5706 : if (vma_entry_is(&vma->vma, VMA_AREA_SYSVIPC))
477 : 5 : ret = vma->vma.shmid;
478 [ + + ]: 5701 : else if (vma_entry_is(&vma->vma, VMA_ANON_SHARED))
479 : 44 : ret = get_shmem_fd(pid, &vma->vma);
480 [ + + ]: 5657 : else if (vma_entry_is(&vma->vma, VMA_FILE_SHARED))
481 : 8 : ret = get_filemap_fd(pid, &vma->vma);
482 [ - + ]: 5649 : else if (vma_entry_is(&vma->vma, VMA_AREA_SOCKET))
483 : 0 : ret = get_socket_fd(pid, &vma->vma);
484 : : else
485 : 5649 : continue;
486 : :
487 [ - + ]: 57 : if (ret < 0) {
488 : 0 : pr_err("Can't fixup fd\n");
489 : 0 : break;
490 : : }
491 : :
492 : 57 : pr_info("\t`- setting %d as mapping fd\n", ret);
493 : 57 : vma->vma.fd = ret;
494 : : }
495 : :
496 [ + - ]: 349 : return ret < 0 ? -1 : 0;
497 : : }
498 : :
499 : : static rt_sigaction_t sigchld_act;
500 : 349 : static int prepare_sigactions(int pid)
501 : : {
502 : : rt_sigaction_t act, oact;
503 : : int fd_sigact;
504 : : SaEntry *e;
505 : : int sig;
506 : 349 : int ret = -1;
507 : :
508 : 349 : fd_sigact = open_image_ro(CR_FD_SIGACT, pid);
509 [ + - ]: 349 : if (fd_sigact < 0)
510 : : return -1;
511 : :
512 [ + + ]: 22685 : for (sig = 1; sig <= SIGMAX; sig++) {
513 [ + + ]: 22336 : if (sig == SIGKILL || sig == SIGSTOP)
514 : 698 : continue;
515 : :
516 : 21638 : ret = pb_read_one_eof(fd_sigact, &e, PB_SIGACT);
517 [ - + ]: 21638 : if (ret == 0) {
518 [ # # ]: 0 : if (sig != SIGMAX_OLD + 1) { /* backward compatibility */
519 : 0 : pr_err("Unexpected EOF %d\n", sig);
520 : 0 : ret = -1;
521 : 0 : break;
522 : : }
523 : 0 : pr_warn("This format of sigacts-%d.img is depricated\n", pid);
524 : 0 : break;
525 : : }
526 [ + - ]: 21638 : if (ret < 0)
527 : : break;
528 : :
529 : 21638 : ASSIGN_TYPED(act.rt_sa_handler, e->sigaction);
530 : 21638 : ASSIGN_TYPED(act.rt_sa_flags, e->flags);
531 : 21638 : ASSIGN_TYPED(act.rt_sa_restorer, e->restorer);
532 : 21638 : ASSIGN_TYPED(act.rt_sa_mask.sig[0], e->mask);
533 : :
534 : 21638 : sa_entry__free_unpacked(e, NULL);
535 : :
536 [ + + ]: 21638 : if (sig == SIGCHLD) {
537 : 349 : sigchld_act = act;
538 : 349 : continue;
539 : : }
540 : : /*
541 : : * A pure syscall is used, because glibc
542 : : * sigaction overwrites se_restorer.
543 : : */
544 : 21289 : ret = sys_sigaction(sig, &act, &oact, sizeof(rt_sigset_t));
545 [ - + ]: 21289 : if (ret == -1) {
546 : 0 : pr_err("%d: Can't restore sigaction: %m\n", pid);
547 : 0 : goto err;
548 : : }
549 : : }
550 : :
551 : : err:
552 : 349 : close_safe(&fd_sigact);
553 : : return ret;
554 : : }
555 : :
556 : 349 : static int pstree_wait_helpers()
557 : : {
558 : : struct pstree_item *pi;
559 : :
560 [ + + ]: 543 : list_for_each_entry(pi, ¤t->children, sibling) {
561 : : int status, ret;
562 : :
563 [ + + ]: 194 : if (pi->state != TASK_HELPER)
564 : 189 : continue;
565 : :
566 : : /* Check, that a helper completed. */
567 : 5 : ret = waitpid(pi->pid.virt, &status, 0);
568 [ + + ]: 5 : if (ret == -1) {
569 [ + - ]: 3 : if (errno == ECHILD)
570 : 3 : continue; /* It has been waited in sigchld_handler */
571 : 0 : pr_err("waitpid(%d) failed\n", pi->pid.virt);
572 : : return -1;
573 : : }
574 [ + - ][ - + ]: 2 : if (!WIFEXITED(status) || WEXITSTATUS(status)) {
575 : 194 : pr_err("%d exited with non-zero code (%d,%d)\n", pi->pid.virt,
576 : : WEXITSTATUS(status), WTERMSIG(status));
577 : : return -1;
578 : : }
579 : :
580 : : }
581 : :
582 : : return 0;
583 : : }
584 : :
585 : :
586 : 349 : static int restore_one_alive_task(int pid, CoreEntry *core)
587 : : {
588 : 349 : pr_info("Restoring resources\n");
589 : :
590 [ + - ]: 349 : if (pstree_wait_helpers())
591 : : return -1;
592 : :
593 [ + - ]: 349 : if (prepare_fds(current))
594 : : return -1;
595 : :
596 [ + - ]: 349 : if (prepare_fs(pid))
597 : : return -1;
598 : :
599 [ + - ]: 349 : if (prepare_sigactions(pid))
600 : : return -1;
601 : :
602 : 349 : log_closedir();
603 : :
604 [ + - ]: 349 : if (open_vmas(pid))
605 : : return -1;
606 : :
607 : 349 : return sigreturn_restore(pid, core);
608 : : }
609 : :
610 : 6 : static void zombie_prepare_signals(void)
611 : : {
612 : : sigset_t blockmask;
613 : : int sig;
614 : : struct sigaction act;
615 : :
616 : 6 : sigfillset(&blockmask);
617 : 6 : sigprocmask(SIG_UNBLOCK, &blockmask, NULL);
618 : :
619 : 6 : memset(&act, 0, sizeof(act));
620 : : act.sa_handler = SIG_DFL;
621 : :
622 [ + + ]: 390 : for (sig = 1; sig <= SIGMAX; sig++)
623 : 384 : sigaction(sig, &act, NULL);
624 : 6 : }
625 : :
626 : : #define SIG_FATAL_MASK ( \
627 : : (1 << SIGHUP) |\
628 : : (1 << SIGINT) |\
629 : : (1 << SIGQUIT) |\
630 : : (1 << SIGILL) |\
631 : : (1 << SIGTRAP) |\
632 : : (1 << SIGABRT) |\
633 : : (1 << SIGIOT) |\
634 : : (1 << SIGBUS) |\
635 : : (1 << SIGFPE) |\
636 : : (1 << SIGKILL) |\
637 : : (1 << SIGUSR1) |\
638 : : (1 << SIGSEGV) |\
639 : : (1 << SIGUSR2) |\
640 : : (1 << SIGPIPE) |\
641 : : (1 << SIGALRM) |\
642 : : (1 << SIGTERM) |\
643 : : (1 << SIGXCPU) |\
644 : : (1 << SIGXFSZ) |\
645 : : (1 << SIGVTALRM)|\
646 : : (1 << SIGPROF) |\
647 : : (1 << SIGPOLL) |\
648 : : (1 << SIGIO) |\
649 : : (1 << SIGSYS) |\
650 : : (1 << SIGUNUSED)|\
651 : : (1 << SIGSTKFLT)|\
652 : : (1 << SIGPWR) \
653 : : )
654 : :
655 : : static inline int sig_fatal(int sig)
656 : : {
657 [ # # ][ # # ]: 0 : return (sig > 0) && (sig < SIGMAX) && (SIG_FATAL_MASK & (1UL << sig));
658 : : }
659 : :
660 : : struct task_entries *task_entries;
661 : :
662 : 0 : static int restore_one_fake(void)
663 : : {
664 : : /* We should wait here, otherwise last_pid will be changed. */
665 : 0 : futex_wait_while(&task_entries->start, CR_STATE_FORKING);
666 : 0 : futex_wait_while(&task_entries->start, CR_STATE_RESTORE_PGID);
667 : 0 : return 0;
668 : : }
669 : :
670 : 6 : static int restore_one_zombie(int pid, int exit_code)
671 : : {
672 : 6 : pr_info("Restoring zombie with %d code\n", exit_code);
673 : :
674 [ + - ]: 6 : if (task_entries != NULL) {
675 : 6 : restore_finish_stage(CR_STATE_RESTORE);
676 : 6 : zombie_prepare_signals();
677 : 6 : restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
678 : : }
679 : :
680 [ - + ]: 6 : if (exit_code & 0x7f) {
681 : : int signr;
682 : :
683 : 0 : signr = exit_code & 0x7F;
684 [ # # ]: 0 : if (!sig_fatal(signr)) {
685 : 0 : pr_warn("Exit with non fatal signal ignored\n");
686 : 0 : signr = SIGABRT;
687 : : }
688 : :
689 [ # # ]: 0 : if (kill(pid, signr) < 0)
690 : 0 : pr_perror("Can't kill myself, will just exit");
691 : :
692 : : exit_code = 0;
693 : : }
694 : :
695 : 6 : exit((exit_code >> 8) & 0x7f);
696 : :
697 : : /* never reached */
698 : : BUG_ON(1);
699 : : return -1;
700 : : }
701 : :
702 : 355 : static int check_core(CoreEntry *core)
703 : : {
704 : 355 : int ret = -1;
705 : :
706 [ - + ]: 355 : if (core->mtype != CORE_ENTRY__MARCH__X86_64) {
707 : 0 : pr_err("Core march mismatch %d\n", (int)core->mtype);
708 : 0 : goto out;
709 : : }
710 : :
711 [ - + ]: 355 : if (!core->tc) {
712 : 0 : pr_err("Core task state data missed\n");
713 : 0 : goto out;
714 : : }
715 : :
716 [ + + ]: 355 : if (core->tc->task_state != TASK_DEAD) {
717 [ - + ]: 349 : if (!core->ids) {
718 : 0 : pr_err("Core IDS data missed for non-zombie\n");
719 : 0 : goto out;
720 : : }
721 : :
722 [ - + ]: 349 : if (!core->thread_info) {
723 : 0 : pr_err("Core info data missed for non-zombie\n");
724 : 0 : goto out;
725 : : }
726 : : }
727 : :
728 : : ret = 0;
729 : : out:
730 : 355 : return ret < 0 ? ret : 0;
731 : : }
732 : :
733 : 355 : static int restore_one_task(int pid)
734 : : {
735 : : int fd, ret;
736 : : CoreEntry *core;
737 : :
738 : 355 : fd = open_image_ro(CR_FD_CORE, pid);
739 [ + - ]: 355 : if (fd < 0)
740 : : return -1;
741 : :
742 : 355 : ret = pb_read_one(fd, &core, PB_CORE);
743 : 355 : close(fd);
744 : :
745 [ + - ]: 355 : if (ret < 0)
746 : : return -1;
747 : :
748 [ + - ]: 355 : if (check_core(core)) {
749 : : ret = -1;
750 : : goto out;
751 : : }
752 : :
753 [ + + - ]: 355 : switch ((int)core->tc->task_state) {
754 : : case TASK_ALIVE:
755 : 349 : ret = restore_one_alive_task(pid, core);
756 : 0 : break;
757 : : case TASK_DEAD:
758 : 6 : ret = restore_one_zombie(pid, core->tc->exit_code);
759 : : break;
760 : : default:
761 : 0 : pr_err("Unknown state in code %d\n", (int)core->tc->task_state);
762 : 0 : ret = -1;
763 : 0 : break;
764 : : }
765 : :
766 : : out:
767 : 0 : core_entry__free_unpacked(core, NULL);
768 : : return ret;
769 : : }
770 : :
771 : : /* All arguments should be above stack, because it grows down */
772 : : struct cr_clone_arg {
773 : : char stack[PAGE_SIZE];
774 : : char stack_ptr[0];
775 : : struct pstree_item *item;
776 : : unsigned long clone_flags;
777 : : int fd;
778 : : };
779 : :
780 : 76 : static void write_pidfile(char *pfname, int pid)
781 : : {
782 : : int fd;
783 : :
784 : 76 : fd = open(pfname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
785 [ - + ]: 76 : if (fd == -1) {
786 : 0 : pr_perror("Can't open %s", pfname);
787 : 0 : kill(pid, SIGKILL);
788 : 76 : return;
789 : : }
790 : :
791 : 76 : dprintf(fd, "%d", pid);
792 : 76 : close(fd);
793 : : }
794 : :
795 : 1100 : static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone_flags)
796 : : {
797 : 1100 : int ret = -1;
798 : : struct cr_clone_arg ca;
799 : 1100 : pid_t pid = item->pid.virt;
800 : :
801 : 1100 : pr_info("Forking task with %d pid (flags 0x%lx)\n", pid, ns_clone_flags);
802 : :
803 : 1100 : ca.item = item;
804 : 1100 : ca.clone_flags = ns_clone_flags;
805 : :
806 [ + + ]: 1100 : if (!(ca.clone_flags & CLONE_NEWPID)) {
807 : : char buf[32];
808 : :
809 : 948 : ca.fd = open(LAST_PID_PATH, O_RDWR);
810 [ - + ]: 948 : if (ca.fd < 0) {
811 : 0 : pr_perror("%d: Can't open %s", pid, LAST_PID_PATH);
812 : : goto err;
813 : : }
814 : :
815 [ - + ]: 948 : if (flock(ca.fd, LOCK_EX)) {
816 : 0 : close(ca.fd);
817 : 0 : pr_perror("%d: Can't lock %s", pid, LAST_PID_PATH);
818 : : goto err;
819 : : }
820 : :
821 : 948 : snprintf(buf, sizeof(buf), "%d", pid - 1);
822 [ + - ]: 948 : if (write_img_buf(ca.fd, buf, strlen(buf)))
823 : : goto err_unlock;
824 : : } else {
825 : 152 : ca.fd = -1;
826 [ - + ]: 152 : BUG_ON(pid != INIT_PID);
827 : : }
828 : :
829 [ + + ]: 1100 : if (ca.clone_flags & CLONE_NEWNET)
830 : : /*
831 : : * When restoring a net namespace we need to communicate
832 : : * with the original (i.e. -- init) one. Thus, prepare for
833 : : * that before we leave the existing namespaces.
834 : : */
835 [ + - ]: 152 : if (netns_pre_create())
836 : : goto err_unlock;
837 : :
838 : 1100 : ret = clone(restore_task_with_children, ca.stack_ptr,
839 : 1100 : ca.clone_flags | SIGCHLD, &ca);
840 : :
841 [ - + ]: 617 : if (ret < 0)
842 : 0 : pr_perror("Can't fork for %d", pid);
843 : :
844 [ + + ]: 617 : if (ca.clone_flags & CLONE_NEWPID)
845 : 76 : item->pid.real = ret;
846 : :
847 [ + + ][ + + ]: 617 : if (opts.pidfile && root_item == item)
848 : 76 : write_pidfile(opts.pidfile, ret);
849 : :
850 : : err_unlock:
851 [ + + ]: 617 : if (ca.fd >= 0) {
852 [ - + ]: 541 : if (flock(ca.fd, LOCK_UN))
853 : 0 : pr_perror("%d: Can't unlock %s", pid, LAST_PID_PATH);
854 : :
855 : 541 : close(ca.fd);
856 : : }
857 : : err:
858 : 617 : return ret;
859 : : }
860 : :
861 : 299 : static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
862 : : {
863 : : struct pstree_item *pi;
864 : 299 : pid_t pid = siginfo->si_pid;
865 : : int status;
866 : : int exit;
867 : :
868 : 299 : exit = siginfo->si_code & CLD_EXITED;
869 : 299 : status = siginfo->si_status;
870 [ + - ][ + - ]: 299 : if (!current || status)
871 : : goto err;
872 : :
873 [ + - ]: 302 : while (pid) {
874 : 302 : pid = waitpid(-1, &status, WNOHANG);
875 [ + + ]: 302 : if (pid <= 0)
876 : 299 : return;
877 : :
878 : 3 : exit = WIFEXITED(status);
879 [ + - ]: 3 : status = exit ? WEXITSTATUS(status) : WTERMSIG(status);
880 [ + - ]: 3 : if (status)
881 : : break;
882 : :
883 : : /* Exited (with zero code) helpers are OK */
884 [ + - ]: 3 : list_for_each_entry(pi, ¤t->children, sibling)
885 [ - + ]: 3 : if (pi->pid.virt == siginfo->si_pid)
886 : : break;
887 : :
888 [ - + ]: 3 : BUG_ON(&pi->sibling == ¤t->children);
889 [ + - ]: 302 : if (pi->state != TASK_HELPER)
890 : : break;
891 : : }
892 : :
893 : : err:
894 [ # # ]: 0 : if (exit)
895 : 0 : pr_err("%d exited, status=%d\n", pid, status);
896 : : else
897 : 0 : pr_err("%d killed by signal %d\n", pid, status);
898 : :
899 : 299 : futex_abort_and_wake(&task_entries->nr_in_progress);
900 : : }
901 : :
902 : 616 : static void restore_sid(void)
903 : : {
904 : : pid_t sid;
905 : :
906 : : /*
907 : : * SID can only be reset to pid or inherited from parent.
908 : : * Thus we restore it right here to let our kids inherit
909 : : * one in case they need it.
910 : : *
911 : : * PGIDs are restored late when all tasks are forked and
912 : : * we can call setpgid() on custom values.
913 : : */
914 : :
915 [ + + ]: 616 : if (current->pid.virt == current->sid) {
916 : 513 : pr_info("Restoring %d to %d sid\n", current->pid.virt, current->sid);
917 : 513 : sid = setsid();
918 [ - + ]: 513 : if (sid != current->sid) {
919 : 0 : pr_perror("Can't restore sid (%d)", sid);
920 : 0 : exit(1);
921 : : }
922 : : } else {
923 : 103 : sid = getsid(getpid());
924 [ - + ]: 103 : if (sid != current->sid) {
925 : : /* Skip the root task if it's not init */
926 [ # # ][ # # ]: 0 : if (current == root_item && root_item->pid.virt != INIT_PID)
927 : 616 : return;
928 : 0 : pr_err("Requested sid %d doesn't match inherited %d\n",
929 : : current->sid, sid);
930 : 0 : exit(1);
931 : : }
932 : : }
933 : : }
934 : :
935 : 355 : static void restore_pgid(void)
936 : : {
937 : : pid_t pgid;
938 : :
939 : 355 : pr_info("Restoring %d to %d pgid\n", current->pid.virt, current->pgid);
940 : :
941 : 355 : pgid = getpgrp();
942 [ + + ]: 355 : if (current->pgid == pgid)
943 : 355 : return;
944 : :
945 : 5 : pr_info("\twill call setpgid, mine pgid is %d\n", pgid);
946 [ - + ]: 5 : if (setpgid(0, current->pgid) != 0) {
947 : 0 : pr_perror("Can't restore pgid (%d/%d->%d)", current->pid.virt, pgid, current->pgid);
948 : 0 : exit(1);
949 : : }
950 : : }
951 : :
952 : 355 : static int mount_proc(void)
953 : : {
954 : : int ret;
955 : 355 : char proc_mountpoint[] = "crtools-proc.XXXXXX";
956 : :
957 [ - + ]: 355 : if (mkdtemp(proc_mountpoint) == NULL) {
958 : 0 : pr_perror("mkdtemp failed %s", proc_mountpoint);
959 : : return -1;
960 : : }
961 : :
962 : 355 : pr_info("Mount procfs in %s\n", proc_mountpoint);
963 [ - + ]: 355 : if (mount("proc", proc_mountpoint, "proc", MS_MGC_VAL, NULL)) {
964 : 0 : pr_perror("mount failed");
965 : 0 : ret = -1;
966 : 0 : goto out_rmdir;
967 : : }
968 : :
969 : 355 : ret = set_proc_mountpoint(proc_mountpoint);
970 : :
971 [ - + ]: 355 : if (umount2(proc_mountpoint, MNT_DETACH) == -1) {
972 : 0 : pr_perror("Can't umount %s", proc_mountpoint);
973 : : return -1;
974 : : }
975 : :
976 : : out_rmdir:
977 [ - + ]: 355 : if (rmdir(proc_mountpoint) == -1) {
978 : 355 : pr_perror("Can't remove %s", proc_mountpoint);
979 : : return -1;
980 : : }
981 : :
982 : : return ret;
983 : : }
984 : :
985 : 483 : static int restore_task_with_children(void *_arg)
986 : : {
987 : 483 : struct cr_clone_arg *ca = _arg;
988 : : struct pstree_item *child;
989 : : pid_t pid;
990 : : int ret;
991 : : sigset_t blockmask;
992 : :
993 : 483 : close_safe(&ca->fd);
994 : :
995 : 483 : current = ca->item;
996 : :
997 : 483 : pid = getpid();
998 [ - + ]: 483 : if (current->pid.virt != pid) {
999 : 0 : pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
1000 : 0 : exit(-1);
1001 : : }
1002 : :
1003 : 483 : ret = log_init_by_pid();
1004 [ - + ]: 483 : if (ret < 0)
1005 : 0 : exit(1);
1006 : :
1007 : : /* Restore root task */
1008 [ + + ]: 483 : if (current->parent == NULL) {
1009 [ - + ]: 214 : if (collect_mount_info())
1010 : 0 : exit(-1);
1011 : :
1012 [ - + ]: 214 : if (prepare_namespace(current->pid.virt, ca->clone_flags))
1013 : 0 : exit(-1);
1014 : :
1015 : : /*
1016 : : * We need non /proc proc mount for restoring pid and mount
1017 : : * namespaces and do not care for the rest of the cases.
1018 : : * Thus -- mount proc at custom location for any new namespace
1019 : : */
1020 [ - + ]: 355 : if (mount_proc())
1021 : 0 : exit(-1);
1022 : :
1023 [ - + ]: 355 : if (root_prepare_shared())
1024 : 0 : exit(-1);
1025 : : }
1026 : :
1027 : : /*
1028 : : * The block mask will be restored in sigresturn.
1029 : : *
1030 : : * TODO: This code should be removed, when a freezer will be added.
1031 : : */
1032 : 624 : sigfillset(&blockmask);
1033 : 624 : sigdelset(&blockmask, SIGCHLD);
1034 : 624 : ret = sigprocmask(SIG_BLOCK, &blockmask, NULL);
1035 [ - + ]: 624 : if (ret) {
1036 : 0 : pr_perror("%d: Can't block signals", current->pid.virt);
1037 : 0 : exit(1);
1038 : : }
1039 : :
1040 [ - + ]: 624 : if (read_vmas(pid))
1041 : 0 : exit(1);
1042 : :
1043 : 624 : pr_info("Restoring children:\n");
1044 [ + + ]: 1564 : list_for_each_entry(child, ¤t->children, sibling) {
1045 [ + + ]: 948 : if (!restore_before_setsid(child))
1046 : 934 : continue;
1047 : :
1048 [ + + ][ - + ]: 14 : BUG_ON(child->born_sid != -1 && getsid(getpid()) != child->born_sid);
1049 : :
1050 : 14 : ret = fork_with_pid(child, 0);
1051 [ - + ]: 6 : if (ret < 0)
1052 : 0 : exit(1);
1053 : : }
1054 : :
1055 : 616 : restore_sid();
1056 : :
1057 : 616 : pr_info("Restoring children:\n");
1058 [ + + ]: 1067 : list_for_each_entry(child, ¤t->children, sibling) {
1059 [ + + ]: 712 : if (restore_before_setsid(child))
1060 : 6 : continue;
1061 : 706 : ret = fork_with_pid(child, 0);
1062 [ - + ]: 445 : if (ret < 0)
1063 : 0 : exit(1);
1064 : : }
1065 : :
1066 [ + + ]: 355 : if (current->pgid == current->pid.virt)
1067 : 257 : restore_pgid();
1068 : :
1069 : 355 : restore_finish_stage(CR_STATE_FORKING);
1070 : :
1071 [ + + ]: 355 : if (current->pgid != current->pid.virt)
1072 : 98 : restore_pgid();
1073 : :
1074 [ - + ]: 355 : if (current->state == TASK_HELPER)
1075 : 0 : return restore_one_fake();
1076 : :
1077 : 355 : restore_finish_stage(CR_STATE_RESTORE_PGID);
1078 : 355 : return restore_one_task(current->pid.virt);
1079 : : }
1080 : :
1081 : 878 : static inline int stage_participants(int next_stage)
1082 : : {
1083 [ + + + - ]: 878 : switch (next_stage) {
1084 : : case CR_STATE_FORKING:
1085 : 380 : return task_entries->nr_tasks + task_entries->nr_helpers;
1086 : : case CR_STATE_RESTORE_PGID:
1087 : 166 : return task_entries->nr_tasks;
1088 : : case CR_STATE_RESTORE:
1089 : : case CR_STATE_RESTORE_SIGCHLD:
1090 : 332 : return task_entries->nr_threads;
1091 : : }
1092 : :
1093 : 0 : BUG();
1094 : 878 : return -1;
1095 : : }
1096 : :
1097 : 498 : static int restore_switch_stage(int next_stage)
1098 : : {
1099 : : int ret;
1100 : 498 : futex_t *np = &task_entries->nr_in_progress;
1101 : :
1102 : 498 : futex_wait_while_gt(np, 0);
1103 : 498 : ret = (int)futex_get(np);
1104 [ + - ]: 498 : if (ret < 0)
1105 : : return ret;
1106 : :
1107 : 498 : futex_set(np, stage_participants(next_stage));
1108 : 498 : futex_set_and_wake(&task_entries->start, next_stage);
1109 : 498 : return 0;
1110 : : }
1111 : :
1112 : 380 : static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
1113 : : {
1114 : : int ret;
1115 : : struct sigaction act, old_act;
1116 : :
1117 : 380 : ret = sigaction(SIGCHLD, NULL, &act);
1118 [ - + ]: 380 : if (ret < 0) {
1119 : 0 : pr_perror("sigaction() failed\n");
1120 : : return -1;
1121 : : }
1122 : :
1123 : 380 : act.sa_flags |= SA_NOCLDSTOP | SA_SIGINFO | SA_RESTART;
1124 : 380 : act.sa_sigaction = sigchld_handler;
1125 : 380 : sigemptyset(&act.sa_mask);
1126 : 380 : sigaddset(&act.sa_mask, SIGCHLD);
1127 : :
1128 : 380 : ret = sigaction(SIGCHLD, &act, &old_act);
1129 [ - + ]: 380 : if (ret < 0) {
1130 : 0 : pr_perror("sigaction() failed\n");
1131 : : return -1;
1132 : : }
1133 : :
1134 : : /*
1135 : : * FIXME -- currently we assume that all the tasks live
1136 : : * in the same set of namespaces. This is done to debug
1137 : : * the ns contents dumping/restoring. Need to revisit
1138 : : * this later.
1139 : : */
1140 : :
1141 [ + + ]: 380 : if (init->pid.virt == INIT_PID) {
1142 [ - + ]: 152 : if (!(opts->namespaces_flags & CLONE_NEWPID)) {
1143 : 0 : pr_err("This process tree can only be restored "
1144 : : "in a new pid namespace.\n"
1145 : : "crtools should be re-executed with the "
1146 : : "\"--namespace pid\" option.\n");
1147 : : return -1;
1148 : : }
1149 [ - + ]: 228 : } else if (opts->namespaces_flags & CLONE_NEWPID) {
1150 : 0 : pr_err("Can't restore pid namespace without the process init\n");
1151 : : return -1;
1152 : : }
1153 : :
1154 : 380 : futex_set(&task_entries->nr_in_progress, stage_participants(CR_STATE_FORKING));
1155 : :
1156 : 380 : ret = fork_with_pid(init, opts->namespaces_flags);
1157 [ + - ]: 166 : if (ret < 0)
1158 : : return -1;
1159 : :
1160 : 166 : pr_info("Wait until all tasks are forked\n");
1161 : 166 : ret = restore_switch_stage(CR_STATE_RESTORE_PGID);
1162 [ + - ]: 166 : if (ret < 0)
1163 : : goto out;
1164 : :
1165 : :
1166 : 166 : pr_info("Wait until all tasks restored pgid\n");
1167 : 166 : ret = restore_switch_stage(CR_STATE_RESTORE);
1168 [ + - ]: 166 : if (ret < 0)
1169 : : goto out;
1170 : :
1171 : 166 : pr_info("Wait until all tasks are restored\n");
1172 : 166 : ret = restore_switch_stage(CR_STATE_RESTORE_SIGCHLD);
1173 [ + - ]: 166 : if (ret < 0)
1174 : : goto out;
1175 : :
1176 : 166 : futex_wait_until(&task_entries->nr_in_progress, 0);
1177 : :
1178 : : /* Restore SIGCHLD here to skip SIGCHLD from a network sctip */
1179 : 166 : ret = sigaction(SIGCHLD, &old_act, NULL);
1180 [ - + ]: 166 : if (ret < 0) {
1181 : 0 : pr_perror("sigaction() failed\n");
1182 : : goto out;
1183 : : }
1184 : :
1185 : 166 : network_unlock();
1186 : : out:
1187 [ - + ]: 166 : if (ret < 0) {
1188 : : struct pstree_item *pi;
1189 : 0 : pr_err("Someone can't be restored\n");
1190 : :
1191 [ # # ]: 0 : if (opts->namespaces_flags & CLONE_NEWPID) {
1192 : : /* Kill init */
1193 [ # # ]: 0 : if (root_item->pid.real > 0)
1194 : 0 : kill(root_item->pid.real, SIGKILL);
1195 : : } else {
1196 [ # # ]: 0 : for_each_pstree_item(pi)
1197 [ # # ]: 0 : if (pi->pid.virt > 0)
1198 : 0 : kill(pi->pid.virt, SIGKILL);
1199 : : }
1200 : : return 1;
1201 : : }
1202 : :
1203 : 166 : pr_info("Go on!!!\n");
1204 : 166 : futex_set_and_wake(&task_entries->start, CR_STATE_COMPLETE);
1205 : :
1206 [ - + ]: 166 : if (!opts->restore_detach)
1207 : 166 : wait(NULL);
1208 : : return 0;
1209 : : }
1210 : :
1211 : 380 : static int prepare_task_entries()
1212 : : {
1213 : 380 : task_entries = mmap(NULL, TASK_ENTRIES_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0);
1214 [ - + ]: 380 : if (task_entries == MAP_FAILED) {
1215 : 0 : pr_perror("Can't map shmem");
1216 : 0 : return -1;
1217 : : }
1218 : 380 : task_entries->nr_threads = 0;
1219 : 380 : task_entries->nr_tasks = 0;
1220 : 380 : task_entries->nr_helpers = 0;
1221 : 380 : futex_set(&task_entries->start, CR_STATE_FORKING);
1222 : :
1223 : 380 : return 0;
1224 : : }
1225 : :
1226 : 380 : int cr_restore_tasks(pid_t pid, struct cr_options *opts)
1227 : : {
1228 [ + - ]: 380 : if (check_img_inventory() < 0)
1229 : : return -1;
1230 : :
1231 [ + - ]: 380 : if (cpu_init() < 0)
1232 : : return -1;
1233 : :
1234 [ + - ]: 380 : if (prepare_task_entries() < 0)
1235 : : return -1;
1236 : :
1237 [ + - ]: 380 : if (prepare_pstree() < 0)
1238 : : return -1;
1239 : :
1240 [ + - ]: 380 : if (crtools_prepare_shared() < 0)
1241 : : return -1;
1242 : :
1243 : 380 : return restore_root_task(root_item, opts);
1244 : : }
1245 : :
1246 : : #define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
1247 : 349 : static long restorer_get_vma_hint(pid_t pid, struct list_head *tgt_vma_list,
1248 : : struct list_head *self_vma_list, long vma_len)
1249 : : {
1250 : : struct vma_area *t_vma, *s_vma;
1251 : 349 : long prev_vma_end = 0;
1252 : : struct vma_area end_vma;
1253 : :
1254 : 349 : end_vma.vma.start = end_vma.vma.end = TASK_SIZE_MAX;
1255 : 349 : prev_vma_end = PAGE_SIZE * 0x10; /* CONFIG_LSM_MMAP_MIN_ADDR=65536 */
1256 : :
1257 : 349 : s_vma = list_first_entry(self_vma_list, struct vma_area, list);
1258 : 349 : t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
1259 : :
1260 : : while (1) {
1261 [ - + ]: 349 : if (prev_vma_end + vma_len > s_vma->vma.start) {
1262 [ # # ]: 0 : if (s_vma->list.next == self_vma_list) {
1263 : 0 : s_vma = &end_vma;
1264 : 0 : continue;
1265 : : }
1266 [ # # ]: 0 : if (s_vma == &end_vma)
1267 : : break;
1268 [ # # ]: 0 : if (prev_vma_end < s_vma->vma.end)
1269 : 0 : prev_vma_end = s_vma->vma.end;
1270 : 0 : s_vma = list_entry(s_vma->list.next, struct vma_area, list);
1271 : 0 : continue;
1272 : : }
1273 : :
1274 [ - + ]: 349 : if (prev_vma_end + vma_len > t_vma->vma.start) {
1275 [ # # ]: 0 : if (t_vma->list.next == tgt_vma_list) {
1276 : 0 : t_vma = &end_vma;
1277 : 0 : continue;
1278 : : }
1279 [ # # ]: 0 : if (t_vma == &end_vma)
1280 : : break;
1281 [ # # ]: 0 : if (prev_vma_end < t_vma->vma.end)
1282 : 0 : prev_vma_end = t_vma->vma.end;
1283 : 0 : t_vma = list_entry(t_vma->list.next, struct vma_area, list);
1284 : 349 : continue;
1285 : : }
1286 : :
1287 : : return prev_vma_end;
1288 : : }
1289 : :
1290 : : return -1;
1291 : : }
1292 : :
1293 : : #define USEC_PER_SEC 1000000L
1294 : :
1295 : : static inline int timeval_valid(struct timeval *tv)
1296 : : {
1297 [ + - ][ - + ]: 12 : return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC);
[ + - ][ - + ]
1298 : : }
1299 : :
1300 : 1047 : static inline int itimer_restore_and_fix(char *n, ItimerEntry *ie,
1301 : : struct itimerval *val)
1302 : : {
1303 [ + - ][ + + ]: 1047 : if (ie->isec == 0 && ie->iusec == 0) {
1304 : 1041 : memzero_p(val);
1305 : 1041 : return 0;
1306 : : }
1307 : :
1308 : 6 : val->it_interval.tv_sec = ie->isec;
1309 : 6 : val->it_interval.tv_usec = ie->iusec;
1310 : :
1311 [ - + ]: 6 : if (!timeval_valid(&val->it_interval)) {
1312 : 0 : pr_err("Invalid timer interval\n");
1313 : 0 : return -1;
1314 : : }
1315 : :
1316 [ + - ][ + - ]: 6 : if (ie->vsec == 0 && ie->vusec == 0) {
1317 : : /*
1318 : : * Remaining time was too short. Set it to
1319 : : * interval to make the timer armed and work.
1320 : : */
1321 : 6 : val->it_value.tv_sec = ie->isec;
1322 : 6 : val->it_value.tv_usec = ie->iusec;
1323 : : } else {
1324 : 0 : val->it_value.tv_sec = ie->vsec;
1325 : 0 : val->it_value.tv_usec = ie->vusec;
1326 : : }
1327 : :
1328 [ - + ]: 6 : if (!timeval_valid(&val->it_value)) {
1329 : 0 : pr_err("Invalid timer value\n");
1330 : 0 : return -1;
1331 : : }
1332 : :
1333 : 6 : pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n,
1334 : : val->it_value.tv_sec, val->it_value.tv_usec,
1335 : : val->it_interval.tv_sec, val->it_interval.tv_usec);
1336 : :
1337 : 1047 : return 0;
1338 : : }
1339 : :
1340 : 349 : static int prepare_itimers(int pid, struct task_restore_core_args *args)
1341 : : {
1342 : 349 : int fd, ret = -1;
1343 : : ItimerEntry *ie;
1344 : :
1345 : 349 : fd = open_image_ro(CR_FD_ITIMERS, pid);
1346 [ + - ]: 349 : if (fd < 0)
1347 : : return fd;
1348 : :
1349 : 349 : ret = pb_read_one(fd, &ie, PB_ITIMERS);
1350 [ + - ]: 349 : if (ret < 0)
1351 : : goto out;
1352 : 349 : ret = itimer_restore_and_fix("real", ie, &args->itimers[0]);
1353 : 349 : itimer_entry__free_unpacked(ie, NULL);
1354 [ + - ]: 349 : if (ret < 0)
1355 : : goto out;
1356 : :
1357 : 349 : ret = pb_read_one(fd, &ie, PB_ITIMERS);
1358 [ + - ]: 349 : if (ret < 0)
1359 : : goto out;
1360 : 349 : ret = itimer_restore_and_fix("virt", ie, &args->itimers[1]);
1361 : 349 : itimer_entry__free_unpacked(ie, NULL);
1362 [ + - ]: 349 : if (ret < 0)
1363 : : goto out;
1364 : :
1365 : 349 : ret = pb_read_one(fd, &ie, PB_ITIMERS);
1366 [ + - ]: 349 : if (ret < 0)
1367 : : goto out;
1368 : 349 : ret = itimer_restore_and_fix("prof", ie, &args->itimers[2]);
1369 : 349 : itimer_entry__free_unpacked(ie, NULL);
1370 : : if (ret < 0)
1371 : : goto out;
1372 : : out:
1373 : 349 : close_safe(&fd);
1374 : : return ret;
1375 : : }
1376 : :
1377 : : static inline int verify_cap_size(CredsEntry *ce)
1378 : : {
1379 [ + - ][ + - ]: 349 : return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) &&
1380 [ + - ][ - + ]: 698 : (ce->n_cap_prm == CR_CAP_SIZE) && (ce->n_cap_bnd == CR_CAP_SIZE));
1381 : : }
1382 : :
1383 : 349 : static int prepare_creds(int pid, struct task_restore_core_args *args)
1384 : : {
1385 : : int fd, ret;
1386 : : CredsEntry *ce;
1387 : :
1388 : 349 : fd = open_image_ro(CR_FD_CREDS, pid);
1389 [ + - ]: 349 : if (fd < 0)
1390 : : return fd;
1391 : :
1392 : 349 : ret = pb_read_one(fd, &ce, PB_CREDS);
1393 : 349 : close_safe(&fd);
1394 : :
1395 [ + - ]: 349 : if (ret < 0)
1396 : : return ret;
1397 [ + - ]: 349 : if (!verify_cap_size(ce))
1398 : : return -1;
1399 : :
1400 : 349 : args->creds = *ce;
1401 : 349 : args->creds.cap_inh = args->cap_inh;
1402 : 349 : memcpy(args->cap_inh, ce->cap_inh, sizeof(args->cap_inh));
1403 : 349 : args->creds.cap_eff = args->cap_eff;
1404 : 349 : memcpy(args->cap_eff, ce->cap_eff, sizeof(args->cap_eff));
1405 : 349 : args->creds.cap_prm = args->cap_prm;
1406 : 349 : memcpy(args->cap_prm, ce->cap_prm, sizeof(args->cap_prm));
1407 : 349 : args->creds.cap_bnd = args->cap_bnd;
1408 : 349 : memcpy(args->cap_bnd, ce->cap_bnd, sizeof(args->cap_bnd));
1409 : :
1410 : : /*
1411 : : * We can set supplementary groups here. This won't affect any
1412 : : * permission checks for us (we're still root) and will not be
1413 : : * reset by subsequent creds changes in restorer.
1414 : : */
1415 : :
1416 : : BUILD_BUG_ON(sizeof(*ce->groups) != sizeof(gid_t));
1417 [ - + ]: 349 : if (setgroups(ce->n_groups, ce->groups) < 0) {
1418 : 0 : pr_perror("Can't set supplementary groups");
1419 : : return -1;
1420 : : }
1421 : :
1422 : 349 : creds_entry__free_unpacked(ce, NULL);
1423 : :
1424 : : /* XXX -- validate creds here? */
1425 : :
1426 : : return 0;
1427 : : }
1428 : :
1429 : 698 : static VmaEntry *vma_list_remap(void *addr, unsigned long len, struct list_head *vmas)
1430 : : {
1431 : : VmaEntry *vma, *ret;
1432 : : struct vma_area *vma_area;
1433 : :
1434 : 698 : ret = vma = mmap(addr, len, PROT_READ | PROT_WRITE,
1435 : : MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
1436 [ - + ]: 698 : if (vma != addr) {
1437 : 0 : pr_perror("Can't remap vma area");
1438 : 0 : return NULL;
1439 : : }
1440 : :
1441 [ + + ]: 26743 : list_for_each_entry(vma_area, vmas, list) {
1442 : 26045 : *vma = vma_area->vma;
1443 : 26045 : vma++;
1444 : : }
1445 : :
1446 : 698 : vma->start = 0;
1447 : 698 : free_mappings(vmas);
1448 : :
1449 : 698 : return ret;
1450 : : }
1451 : :
1452 : 349 : static int prepare_mm(pid_t pid, struct task_restore_core_args *args)
1453 : : {
1454 : 349 : int fd, exe_fd, ret = -1;
1455 : : MmEntry *mm;
1456 : :
1457 : 349 : fd = open_image_ro(CR_FD_MM, pid);
1458 [ + - ]: 349 : if (fd < 0)
1459 : : return -1;
1460 : :
1461 [ - + ]: 349 : if (pb_read_one(fd, &mm, PB_MM) < 0) {
1462 : 0 : close_safe(&fd);
1463 : : return -1;
1464 : : }
1465 : :
1466 : 349 : args->mm = *mm;
1467 : 349 : args->mm.n_mm_saved_auxv = 0;
1468 : 349 : args->mm.mm_saved_auxv = NULL;
1469 : :
1470 [ - + ]: 349 : if (mm->n_mm_saved_auxv > AT_VECTOR_SIZE) {
1471 : 0 : pr_err("Image corrupted on pid %d\n", pid);
1472 : 0 : goto out;
1473 : : }
1474 : :
1475 : 349 : args->mm_saved_auxv_size = pb_repeated_size(mm, mm_saved_auxv);
1476 : 349 : memcpy(args->mm_saved_auxv, mm->mm_saved_auxv,
1477 : : args->mm_saved_auxv_size);
1478 : :
1479 : 349 : exe_fd = open_reg_by_id(args->mm.exe_file_id);
1480 [ + - ]: 349 : if (exe_fd < 0)
1481 : : goto out;
1482 : :
1483 : 349 : args->fd_exe_link = exe_fd;
1484 : 349 : ret = 0;
1485 : : out:
1486 : 349 : mm_entry__free_unpacked(mm, NULL);
1487 : 349 : close(fd);
1488 : : return ret;
1489 : : }
1490 : :
1491 : : static void *restorer;
1492 : : static unsigned long restorer_len;
1493 : :
1494 : 355 : static int prepare_restorer_blob(void)
1495 : : {
1496 : : /*
1497 : : * We map anonymous mapping, not mremap the restorer itself later.
1498 : : * Otherwise the resoter vma would be tied to crtools binary which
1499 : : * in turn will lead to set-exe-file prctl to fail with EBUSY.
1500 : : */
1501 : :
1502 : 355 : restorer_len = round_up(sizeof(restorer_blob), PAGE_SIZE);
1503 : 355 : restorer = mmap(NULL, restorer_len,
1504 : : PROT_READ | PROT_WRITE | PROT_EXEC,
1505 : : MAP_PRIVATE | MAP_ANON, 0, 0);
1506 [ - + ]: 355 : if (restorer == MAP_FAILED) {
1507 : 0 : pr_perror("Can't map restorer code");
1508 : 0 : return -1;
1509 : : }
1510 : :
1511 : 355 : memcpy(restorer, &restorer_blob, sizeof(restorer_blob));
1512 : 355 : return 0;
1513 : : }
1514 : :
1515 : 349 : static int remap_restorer_blob(void *addr)
1516 : : {
1517 : : void *mem;
1518 : :
1519 : 349 : mem = mremap(restorer, restorer_len, restorer_len,
1520 : : MREMAP_FIXED | MREMAP_MAYMOVE, addr);
1521 [ - + ]: 349 : if (mem != addr) {
1522 : 0 : pr_perror("Can't remap restorer blob");
1523 : 349 : return -1;
1524 : : }
1525 : :
1526 : : return 0;
1527 : : }
1528 : :
1529 : 381 : static int validate_sched_parm(struct rst_sched_param *sp)
1530 : : {
1531 [ + - ]: 381 : if ((sp->nice < -20) || (sp->nice > 19))
1532 : : return 0;
1533 : :
1534 [ + + - ]: 381 : switch (sp->policy) {
1535 : : case SCHED_RR:
1536 : : case SCHED_FIFO:
1537 : 2 : return ((sp->prio > 0) && (sp->prio < 100));
1538 : : case SCHED_IDLE:
1539 : : case SCHED_OTHER:
1540 : : case SCHED_BATCH:
1541 : 381 : return sp->prio == 0;
1542 : : }
1543 : :
1544 : : return 0;
1545 : : }
1546 : :
1547 : 381 : static int prep_sched_info(struct rst_sched_param *sp, ThreadCoreEntry *tc)
1548 : : {
1549 [ - + ]: 381 : if (!tc->has_sched_policy) {
1550 : 0 : sp->policy = SCHED_OTHER;
1551 : 0 : sp->nice = 0;
1552 : 0 : return 0;
1553 : : }
1554 : :
1555 : 381 : sp->policy = tc->sched_policy;
1556 : 381 : sp->nice = tc->sched_nice;
1557 : 381 : sp->prio = tc->sched_prio;
1558 : :
1559 [ - + ]: 381 : if (!validate_sched_parm(sp)) {
1560 : 0 : pr_err("Inconsistent sched params received (%d.%d.%d)\n",
1561 : : sp->policy, sp->nice, sp->prio);
1562 : 381 : return -1;
1563 : : }
1564 : :
1565 : : return 0;
1566 : : }
1567 : :
1568 : 381 : static bool valid_xsave_frame(CoreEntry *core)
1569 : : {
1570 : 381 : struct xsave_struct *x = NULL;
1571 : :
1572 [ - + ]: 381 : if (core->thread_info->fpregs->n_st_space < ARRAY_SIZE(x->i387.st_space)) {
1573 : 0 : pr_err("Corruption in FPU st_space area "
1574 : : "(got %li but %li expected)\n",
1575 : : (long)core->thread_info->fpregs->n_st_space,
1576 : : (long)ARRAY_SIZE(x->i387.st_space));
1577 : : return false;
1578 : : }
1579 : :
1580 [ - + ]: 381 : if (core->thread_info->fpregs->n_xmm_space < ARRAY_SIZE(x->i387.xmm_space)) {
1581 : 0 : pr_err("Corruption in FPU xmm_space area "
1582 : : "(got %li but %li expected)\n",
1583 : : (long)core->thread_info->fpregs->n_st_space,
1584 : : (long)ARRAY_SIZE(x->i387.xmm_space));
1585 : : return false;
1586 : : }
1587 : :
1588 [ - + ]: 381 : if (cpu_has_feature(X86_FEATURE_XSAVE)) {
1589 [ # # ]: 0 : if (!core->thread_info->fpregs->xsave) {
1590 : 0 : pr_err("FPU xsave area is missing, "
1591 : : "but host cpu requires it\n");
1592 : : return false;
1593 : : }
1594 [ # # ]: 0 : if (core->thread_info->fpregs->xsave->n_ymmh_space < ARRAY_SIZE(x->ymmh.ymmh_space)) {
1595 : 0 : pr_err("Corruption in FPU ymmh_space area "
1596 : : "(got %li but %li expected)\n",
1597 : : (long)core->thread_info->fpregs->xsave->n_ymmh_space,
1598 : : (long)ARRAY_SIZE(x->ymmh.ymmh_space));
1599 : : return false;
1600 : : }
1601 : : } else {
1602 [ - + ]: 381 : if (core->thread_info->fpregs->xsave) {
1603 : 381 : pr_err("FPU xsave area present, "
1604 : : "but host cpu doesn't support it\n");
1605 : : return false;
1606 : : }
1607 : : return true;
1608 : : }
1609 : :
1610 : : return true;
1611 : : }
1612 : :
1613 : 381 : static void show_rt_xsave_frame(struct xsave_struct *x)
1614 : : {
1615 : 381 : struct fpx_sw_bytes *fpx = (void *)&x->i387.sw_reserved;
1616 : 381 : struct xsave_hdr_struct *xsave_hdr = &x->xsave_hdr;
1617 : 381 : struct i387_fxsave_struct *i387 = &x->i387;
1618 : :
1619 : 381 : pr_debug("xsave runtime structure\n");
1620 : 381 : pr_debug("-----------------------\n");
1621 : :
1622 : 381 : pr_debug("cwd:%x swd:%x twd:%x fop:%x mxcsr:%x mxcsr_mask:%x\n",
1623 : : (int)i387->cwd, (int)i387->swd, (int)i387->twd,
1624 : : (int)i387->fop, (int)i387->mxcsr, (int)i387->mxcsr_mask);
1625 : :
1626 : 381 : pr_debug("magic1:%x extended_size:%x xstate_bv:%lx xstate_size:%x\n",
1627 : : fpx->magic1, fpx->extended_size, fpx->xstate_bv, fpx->xstate_size);
1628 : :
1629 : 381 : pr_debug("xstate_bv: %lx\n", xsave_hdr->xstate_bv);
1630 : :
1631 : 381 : pr_debug("-----------------------\n");
1632 : 381 : }
1633 : :
1634 : 381 : static int sigreturn_prep_xsave_frame(struct thread_restore_args *args, CoreEntry *core)
1635 : : {
1636 : 381 : struct xsave_struct *x = &args->xsave;
1637 : :
1638 : : /*
1639 : : * If no FPU information provided -- we're restoring
1640 : : * old image which has no FPU support, or the dump simply
1641 : : * has no FPU support at all.
1642 : : */
1643 [ - + ]: 381 : if (!core->thread_info->fpregs) {
1644 : 0 : args->has_fpu = false;
1645 : 0 : return 0;
1646 : : }
1647 : :
1648 [ + - ]: 381 : if (!valid_xsave_frame(core))
1649 : : return -1;
1650 : :
1651 : 381 : args->has_fpu = true;
1652 : :
1653 : : #define assign_reg(dst, src, e) do { dst.e = (__typeof__(dst.e))src->e; } while (0)
1654 : : #define assign_array(dst, src, e) memcpy(dst.e, (src)->e, sizeof(dst.e))
1655 : :
1656 : 381 : assign_reg(x->i387, core->thread_info->fpregs, cwd);
1657 : 381 : assign_reg(x->i387, core->thread_info->fpregs, swd);
1658 : 381 : assign_reg(x->i387, core->thread_info->fpregs, twd);
1659 : 381 : assign_reg(x->i387, core->thread_info->fpregs, fop);
1660 : 381 : assign_reg(x->i387, core->thread_info->fpregs, rip);
1661 : 381 : assign_reg(x->i387, core->thread_info->fpregs, rdp);
1662 : 381 : assign_reg(x->i387, core->thread_info->fpregs, mxcsr);
1663 : 381 : assign_reg(x->i387, core->thread_info->fpregs, mxcsr_mask);
1664 : :
1665 : 381 : assign_array(x->i387, core->thread_info->fpregs, st_space);
1666 : 381 : assign_array(x->i387, core->thread_info->fpregs, xmm_space);
1667 : :
1668 [ - + ]: 381 : if (cpu_has_feature(X86_FEATURE_XSAVE)) {
1669 : 0 : struct fpx_sw_bytes *fpx_sw = (void *)&x->i387.sw_reserved;
1670 : : void *magic2;
1671 : :
1672 : 0 : x->xsave_hdr.xstate_bv = XSTATE_FP | XSTATE_SSE | XSTATE_YMM;
1673 : 0 : assign_array(x->ymmh, core->thread_info->fpregs->xsave, ymmh_space);
1674 : :
1675 : 0 : fpx_sw->magic1 = FP_XSTATE_MAGIC1;
1676 : 0 : fpx_sw->xstate_bv = XSTATE_FP | XSTATE_SSE | XSTATE_YMM;
1677 : 0 : fpx_sw->xstate_size = sizeof(struct xsave_struct);
1678 : 0 : fpx_sw->extended_size = sizeof(struct xsave_struct) + FP_XSTATE_MAGIC2_SIZE;
1679 : :
1680 : : /*
1681 : : * This should be at the end of xsave frame.
1682 : : */
1683 : 0 : magic2 = args->__pad + sizeof(struct xsave_struct);
1684 : 0 : *(u32 *)magic2 = FP_XSTATE_MAGIC2;
1685 : : }
1686 : :
1687 : 381 : show_rt_xsave_frame(x);
1688 : :
1689 : : #undef assign_reg
1690 : : #undef assign_array
1691 : :
1692 : 381 : return 0;
1693 : : }
1694 : :
1695 : : extern void __gcov_flush(void) __attribute__((weak));
1696 : 0 : void __gcov_flush(void) {}
1697 : :
1698 : 349 : static int sigreturn_restore(pid_t pid, CoreEntry *core)
1699 : : {
1700 : : long restore_task_vma_len;
1701 : : long restore_thread_vma_len, self_vmas_len, vmas_len;
1702 : :
1703 : 349 : void *mem = MAP_FAILED;
1704 : : void *restore_thread_exec_start;
1705 : : void *restore_task_exec_start;
1706 : :
1707 : : long new_sp, exec_mem_hint;
1708 : : long ret;
1709 : : long restore_bootstrap_len;
1710 : :
1711 : : struct task_restore_core_args *task_args;
1712 : : struct thread_restore_args *thread_args;
1713 : :
1714 : 349 : LIST_HEAD(self_vma_list);
1715 : : int i;
1716 : :
1717 : 349 : pr_info("Restore via sigreturn\n");
1718 : :
1719 : 349 : restore_task_vma_len = 0;
1720 : 349 : restore_thread_vma_len = 0;
1721 : :
1722 : 349 : ret = parse_smaps(pid, &self_vma_list, false);
1723 : 349 : close_proc();
1724 [ + - ]: 349 : if (ret < 0)
1725 : : goto err;
1726 : :
1727 : : /* required to unmap stack _with_ guard page */
1728 : 349 : mark_stack_vma((long) &self_vma_list, &self_vma_list);
1729 : :
1730 : 349 : self_vmas_len = round_up((ret + 1) * sizeof(VmaEntry), PAGE_SIZE);
1731 : 349 : vmas_len = round_up((rst_nr_vmas + 1) * sizeof(VmaEntry), PAGE_SIZE);
1732 : :
1733 : : /* pr_info_vma_list(&self_vma_list); */
1734 : :
1735 : : BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1);
1736 : : BUILD_BUG_ON(sizeof(struct thread_restore_args) & 1);
1737 : : BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE);
1738 : : BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
1739 : :
1740 : 349 : restore_task_vma_len = round_up(sizeof(*task_args), PAGE_SIZE);
1741 : 349 : restore_thread_vma_len = round_up(sizeof(*thread_args) * current->nr_threads, PAGE_SIZE);
1742 : :
1743 : 349 : pr_info("%d threads require %ldK of memory\n",
1744 : : current->nr_threads,
1745 : : KBYTES(restore_thread_vma_len));
1746 : :
1747 : 698 : restore_bootstrap_len = restorer_len +
1748 : 349 : restore_task_vma_len +
1749 : : restore_thread_vma_len +
1750 : 349 : SHMEMS_SIZE + TASK_ENTRIES_SIZE +
1751 : 349 : self_vmas_len + vmas_len +
1752 : : rst_tcp_socks_size;
1753 : :
1754 : : /*
1755 : : * Restorer is a blob (code + args) that will get mapped in some
1756 : : * place, that should _not_ intersect with both -- current mappings
1757 : : * and mappings of the task we're restoring here. The subsequent
1758 : : * call finds the start address for the restorer.
1759 : : *
1760 : : * After the start address is found we populate it with the restorer
1761 : : * parts one by one (some are remap-ed, some are mmap-ed and copied
1762 : : * or inited from scratch).
1763 : : */
1764 : :
1765 : 349 : exec_mem_hint = restorer_get_vma_hint(pid, &rst_vma_list, &self_vma_list,
1766 : : restore_bootstrap_len);
1767 [ - + ]: 349 : if (exec_mem_hint == -1) {
1768 : 0 : pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
1769 : : restore_bootstrap_len);
1770 : 0 : goto err;
1771 : : }
1772 : :
1773 : 349 : pr_info("Found bootstrap VMA hint at: 0x%lx (needs ~%ldK)\n", exec_mem_hint,
1774 : : KBYTES(restore_bootstrap_len));
1775 : :
1776 : 349 : ret = remap_restorer_blob((void *)exec_mem_hint);
1777 [ + - ]: 349 : if (ret < 0)
1778 : : goto err;
1779 : :
1780 : : /*
1781 : : * Prepare a memory map for restorer. Note a thread space
1782 : : * might be completely unused so it's here just for convenience.
1783 : : */
1784 : 349 : restore_thread_exec_start = restorer_sym(exec_mem_hint, __export_restore_thread);
1785 : 349 : restore_task_exec_start = restorer_sym(exec_mem_hint, __export_restore_task);
1786 : :
1787 : 349 : exec_mem_hint += restorer_len;
1788 : :
1789 : : /* VMA we need to run task_restore code */
1790 : 349 : mem = mmap((void *)exec_mem_hint,
1791 : 349 : restore_task_vma_len + restore_thread_vma_len,
1792 : : PROT_READ | PROT_WRITE,
1793 : : MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
1794 [ - + ]: 349 : if (mem != (void *)exec_mem_hint) {
1795 : 0 : pr_err("Can't mmap section for restore code\n");
1796 : 0 : goto err;
1797 : : }
1798 : :
1799 : 349 : memzero(mem, restore_task_vma_len + restore_thread_vma_len);
1800 : 349 : task_args = mem;
1801 : 349 : thread_args = mem + restore_task_vma_len;
1802 : :
1803 : : /*
1804 : : * Get a reference to shared memory area which is
1805 : : * used to signal if shmem restoration complete
1806 : : * from low-level restore code.
1807 : : *
1808 : : * This shmem area is mapped right after the whole area of
1809 : : * sigreturn rt code. Note we didn't allocated it before
1810 : : * but this area is taken into account for 'hint' memory
1811 : : * address.
1812 : : */
1813 : :
1814 : 349 : mem += restore_task_vma_len + restore_thread_vma_len;
1815 : 349 : ret = shmem_remap(rst_shmems, mem, SHMEMS_SIZE);
1816 [ + - ]: 349 : if (ret < 0)
1817 : : goto err;
1818 : 349 : task_args->shmems = mem;
1819 : :
1820 : 349 : mem += SHMEMS_SIZE;
1821 : 349 : ret = shmem_remap(task_entries, mem, TASK_ENTRIES_SIZE);
1822 [ + - ]: 349 : if (ret < 0)
1823 : : goto err;
1824 : 349 : task_args->task_entries = mem;
1825 : :
1826 : 349 : mem += TASK_ENTRIES_SIZE;
1827 : 349 : task_args->self_vmas = vma_list_remap(mem, self_vmas_len, &self_vma_list);
1828 [ + - ]: 349 : if (!task_args->self_vmas)
1829 : : goto err;
1830 : :
1831 : 349 : mem += self_vmas_len;
1832 : 349 : task_args->tgt_vmas = vma_list_remap(mem, vmas_len, &rst_vma_list);
1833 : 349 : task_args->nr_vmas = rst_nr_vmas;
1834 : 349 : task_args->premmapped_addr = (unsigned long) current->rst->premmapped_addr;
1835 : 349 : task_args->premmapped_len = current->rst->premmapped_len;
1836 [ + - ]: 349 : if (!task_args->tgt_vmas)
1837 : : goto err;
1838 : :
1839 : 349 : mem += vmas_len;
1840 [ + - ]: 349 : if (rst_tcp_socks_remap(mem))
1841 : : goto err;
1842 : 349 : task_args->rst_tcp_socks = mem;
1843 : 349 : task_args->rst_tcp_socks_size = rst_tcp_socks_size;
1844 : :
1845 : : /*
1846 : : * Arguments for task restoration.
1847 : : */
1848 : :
1849 [ - + ]: 349 : BUG_ON(core->mtype != CORE_ENTRY__MARCH__X86_64);
1850 : :
1851 : 349 : task_args->logfd = log_get_fd();
1852 : 349 : task_args->loglevel = log_get_loglevel();
1853 : 349 : task_args->sigchld_act = sigchld_act;
1854 : :
1855 : 349 : strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
1856 : :
1857 : : /*
1858 : : * Fill up per-thread data.
1859 : : */
1860 [ + + ]: 730 : for (i = 0; i < current->nr_threads; i++) {
1861 : : int fd_core;
1862 : : CoreEntry *tcore;
1863 : :
1864 : 381 : thread_args[i].pid = current->threads[i].virt;
1865 : :
1866 : : /* skip self */
1867 [ + + ]: 381 : if (thread_args[i].pid == pid) {
1868 : 349 : task_args->t = thread_args + i;
1869 : 349 : tcore = core;
1870 : : } else {
1871 : 32 : fd_core = open_image_ro(CR_FD_CORE, thread_args[i].pid);
1872 [ - + ]: 32 : if (fd_core < 0) {
1873 : 0 : pr_err("Can't open core data for thread %d\n",
1874 : : thread_args[i].pid);
1875 : : goto err;
1876 : : }
1877 : :
1878 : 32 : ret = pb_read_one(fd_core, &tcore, PB_CORE);
1879 : 32 : close(fd_core);
1880 : : }
1881 : :
1882 [ + + ][ - + ]: 381 : if ((tcore->tc || tcore->ids) && thread_args[i].pid != pid) {
[ - + ]
1883 : 0 : pr_err("Thread has optional fields present %d\n",
1884 : : thread_args[i].pid);
1885 : 0 : ret = -1;
1886 : : }
1887 : :
1888 [ - + ]: 381 : if (ret < 0) {
1889 : 0 : pr_err("Can't read core data for thread %d\n",
1890 : : thread_args[i].pid);
1891 : : goto err;
1892 : : }
1893 : :
1894 : 381 : thread_args[i].ta = task_args;
1895 : 381 : thread_args[i].gpregs = *tcore->thread_info->gpregs;
1896 : 381 : thread_args[i].clear_tid_addr = tcore->thread_info->clear_tid_addr;
1897 : :
1898 [ + - ]: 381 : if (tcore->thread_core) {
1899 : 381 : thread_args[i].has_futex = true;
1900 : 381 : thread_args[i].futex_rla = tcore->thread_core->futex_rla;
1901 : 381 : thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len;
1902 : 381 : thread_args[i].has_blk_sigset = tcore->thread_core->has_blk_sigset;
1903 : 381 : thread_args[i].blk_sigset = tcore->thread_core->blk_sigset;
1904 : :
1905 : 381 : ret = prep_sched_info(&thread_args[i].sp, tcore->thread_core);
1906 [ + - ]: 381 : if (ret)
1907 : : goto err;
1908 : : }
1909 : :
1910 [ + - ]: 381 : if (sigreturn_prep_xsave_frame(&thread_args[i], core))
1911 : : goto err;
1912 : :
1913 [ + + ]: 381 : if (thread_args[i].pid != pid)
1914 : 32 : core_entry__free_unpacked(tcore, NULL);
1915 : :
1916 : 381 : pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n",
1917 : : i, thread_args[i].mem_zone.stack,
1918 : : thread_args[i].mem_zone.heap,
1919 : : thread_args[i].mem_zone.rt_sigframe);
1920 : :
1921 : : }
1922 : :
1923 : 349 : task_args->t->blk_sigset = core->tc->blk_sigset;
1924 : 349 : task_args->t->has_blk_sigset = true;
1925 : :
1926 : : /*
1927 : : * Adjust stack.
1928 : : */
1929 : 349 : new_sp = RESTORE_ALIGN_STACK((long)task_args->t->mem_zone.stack,
1930 : : sizeof(task_args->t->mem_zone.stack));
1931 : :
1932 : : /* No longer need it */
1933 : 349 : core_entry__free_unpacked(core, NULL);
1934 : :
1935 : 349 : ret = prepare_itimers(pid, task_args);
1936 [ + - ]: 349 : if (ret < 0)
1937 : : goto err;
1938 : :
1939 : 349 : ret = prepare_creds(pid, task_args);
1940 [ + - ]: 349 : if (ret < 0)
1941 : : goto err;
1942 : :
1943 : 349 : ret = prepare_mm(pid, task_args);
1944 [ + - ]: 349 : if (ret < 0)
1945 : : goto err;
1946 : :
1947 : 349 : mutex_init(&task_args->rst_lock);
1948 : :
1949 : : /*
1950 : : * Now prepare run-time data for threads restore.
1951 : : */
1952 : 349 : task_args->nr_threads = current->nr_threads;
1953 : 349 : task_args->clone_restore_fn = (void *)restore_thread_exec_start;
1954 : 349 : task_args->thread_args = thread_args;
1955 : :
1956 : 349 : close_image_dir();
1957 : :
1958 : 349 : __gcov_flush();
1959 : :
1960 : 0 : pr_info("task_args: %p\n"
1961 : : "task_args->pid: %d\n"
1962 : : "task_args->nr_threads: %d\n"
1963 : : "task_args->clone_restore_fn: %p\n"
1964 : : "task_args->thread_args: %p\n",
1965 : : task_args, task_args->t->pid,
1966 : : task_args->nr_threads,
1967 : : task_args->clone_restore_fn,
1968 : : task_args->thread_args);
1969 : :
1970 : : /*
1971 : : * An indirect call to task_restore, note it never resturns
1972 : : * and restoreing core is extremely destructive.
1973 : : */
1974 : 0 : asm volatile(
1975 : : "movq %0, %%rbx \n"
1976 : : "movq %1, %%rax \n"
1977 : : "movq %2, %%rdi \n"
1978 : : "movq %%rbx, %%rsp \n"
1979 : : "callq *%%rax \n"
1980 : : :
1981 : : : "g"(new_sp),
1982 : : "g"(restore_task_exec_start),
1983 : : "g"(task_args)
1984 : : : "rsp", "rdi", "rsi", "rbx", "rax", "memory");
1985 : :
1986 : : err:
1987 : 0 : free_mappings(&self_vma_list);
1988 : :
1989 : : /* Just to be sure */
1990 : 0 : exit(1);
1991 : : return -1;
1992 : 1141 : }
|