LCOV - code coverage report
Current view: top level - crtools - cr-restore.c (source / functions) Hit Total Coverage
Test: crtools.info Lines: 683 851 80.3 %
Date: 2012-12-28 Functions: 40 42 95.2 %
Branches: 314 544 57.7 %

           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, &current->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, &current->children, sibling)
     885         [ -  + ]:          3 :                         if (pi->pid.virt == siginfo->si_pid)
     886                 :            :                                 break;
     887                 :            : 
     888         [ -  + ]:          3 :                 BUG_ON(&pi->sibling == &current->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, &current->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, &current->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 : }

Generated by: LCOV version 1.9