LCOV - code coverage report
Current view: top level - home/snorch/criu - cr-check.c (source / functions) Hit Total Coverage
Test: coverage3.info Lines: 192 277 69.3 %
Date: 2014-04-22 Functions: 26 26 100.0 %
Branches: 53 108 49.1 %

           Branch data     Line data    Source code
       1                 :            : #include <unistd.h>
       2                 :            : #include <sys/socket.h>
       3                 :            : #include <sys/types.h>
       4                 :            : #include <sys/eventfd.h>
       5                 :            : #include <sys/epoll.h>
       6                 :            : #include <sys/inotify.h>
       7                 :            : #include <sys/signalfd.h>
       8                 :            : #include <sys/ptrace.h>
       9                 :            : #include <sys/wait.h>
      10                 :            : #include <fcntl.h>
      11                 :            : #include <signal.h>
      12                 :            : #include <linux/if.h>
      13                 :            : #include <sys/ioctl.h>
      14                 :            : #include <termios.h>
      15                 :            : 
      16                 :            : #include "proc_parse.h"
      17                 :            : #include "sockets.h"
      18                 :            : #include "crtools.h"
      19                 :            : #include "log.h"
      20                 :            : #include "util-pie.h"
      21                 :            : #include "syscall.h"
      22                 :            : #include "prctl.h"
      23                 :            : #include "files.h"
      24                 :            : #include "sk-inet.h"
      25                 :            : #include "proc_parse.h"
      26                 :            : #include "mount.h"
      27                 :            : #include "tty.h"
      28                 :            : #include "ptrace.h"
      29                 :            : #include "kerndat.h"
      30                 :            : #include "tun.h"
      31                 :            : #include "namespaces.h"
      32                 :            : #include "pstree.h"
      33                 :            : 
      34                 :          2 : static int check_tty(void)
      35                 :            : {
      36                 :          2 :         int master = -1, slave = -1;
      37                 :          2 :         const int lock = 1;
      38                 :            :         struct termios t;
      39                 :            :         char *slavename;
      40                 :            :         int ret = -1;
      41                 :            : 
      42                 :            :         if (ARRAY_SIZE(t.c_cc) < TERMIOS_NCC) {
      43                 :            :                 pr_msg("struct termios has %d @c_cc while "
      44                 :            :                         "at least %d expected.\n",
      45                 :            :                         (int)ARRAY_SIZE(t.c_cc),
      46                 :            :                         TERMIOS_NCC);
      47                 :            :                 goto out;
      48                 :            :         }
      49                 :            : 
      50                 :          2 :         master = open("/dev/ptmx", O_RDWR);
      51         [ -  + ]:          2 :         if (master < 0) {
      52                 :          0 :                 pr_msg("Can't open master pty.\n");
      53                 :          0 :                 goto out;
      54                 :            :         }
      55                 :            : 
      56         [ -  + ]:          2 :         if (ioctl(master, TIOCSPTLCK, &lock)) {
      57                 :          0 :                 pr_msg("Unable to lock pty device.\n");
      58                 :          0 :                 goto out;
      59                 :            :         }
      60                 :            : 
      61                 :          2 :         slavename = ptsname(master);
      62                 :          2 :         slave = open(slavename, O_RDWR);
      63         [ +  - ]:          2 :         if (slave < 0) {
      64         [ -  + ]:          2 :                 if (errno != EIO) {
      65                 :          0 :                         pr_msg("Unexpected error code on locked pty.\n");
      66                 :          0 :                         goto out;
      67                 :            :                 }
      68                 :            :         } else {
      69                 :          0 :                 pr_msg("Managed to open locked pty.\n");
      70                 :          0 :                 goto out;
      71                 :            :         }
      72                 :            : 
      73                 :            :         ret = 0;
      74                 :            : out:
      75                 :          2 :         close_safe(&master);
      76                 :          2 :         close_safe(&slave);
      77                 :          2 :         return ret;
      78                 :            : }
      79                 :            : 
      80                 :          2 : static int check_map_files(void)
      81                 :            : {
      82                 :            :         int ret;
      83                 :            : 
      84                 :          2 :         ret = access("/proc/self/map_files", R_OK);
      85         [ -  + ]:          2 :         if (!ret)
      86                 :            :                 return 0;
      87                 :            : 
      88                 :          0 :         pr_msg("/proc/<pid>/map_files directory is missing.\n");
      89                 :          0 :         return -1;
      90                 :            : }
      91                 :            : 
      92                 :          2 : static int check_sock_diag(void)
      93                 :            : {
      94                 :            :         int ret;
      95                 :            : 
      96                 :          2 :         ret = collect_sockets(0);
      97         [ -  + ]:          2 :         if (!ret)
      98                 :            :                 return 0;
      99                 :            : 
     100                 :          0 :         pr_msg("The sock diag infrastructure is incomplete.\n");
     101                 :          0 :         pr_msg("Make sure you have:\n");
     102                 :          0 :         pr_msg(" 1. *_DIAG kernel config options turned on;\n");
     103                 :          0 :         pr_msg(" 2. *_diag.ko modules loaded (if compiled as modules).\n");
     104                 :          0 :         return -1;
     105                 :            : }
     106                 :            : 
     107                 :          2 : static int check_ns_last_pid(void)
     108                 :            : {
     109                 :            :         int ret;
     110                 :            : 
     111                 :          2 :         ret = access(LAST_PID_PATH, W_OK);
     112         [ -  + ]:          2 :         if (!ret)
     113                 :            :                 return 0;
     114                 :            : 
     115                 :          0 :         pr_msg("%s sysctl is missing.\n", LAST_PID_PATH);
     116                 :          0 :         return -1;
     117                 :            : }
     118                 :            : 
     119                 :          2 : static int check_sock_peek_off(void)
     120                 :            : {
     121                 :            :         int sk;
     122                 :            :         int ret, off, sz;
     123                 :            : 
     124                 :          2 :         sk = socket(PF_UNIX, SOCK_DGRAM, 0);
     125         [ -  + ]:          2 :         if (sk < 0) {
     126                 :          0 :                 pr_perror("Can't create unix socket for check");
     127                 :          0 :                 return -1;
     128                 :            :         }
     129                 :            : 
     130                 :          2 :         sz = sizeof(off);
     131                 :          2 :         ret = getsockopt(sk, SOL_SOCKET, SO_PEEK_OFF, &off, (socklen_t *)&sz);
     132                 :          2 :         close(sk);
     133                 :            : 
     134 [ +  - ][ +  - ]:          2 :         if ((ret == 0) && (off == -1) && (sz == sizeof(int)))
                 [ -  + ]
     135                 :            :                 return 0;
     136                 :            : 
     137                 :          0 :         pr_msg("SO_PEEK_OFF sockoption doesn't work.\n");
     138                 :          0 :         return -1;
     139                 :            : }
     140                 :            : 
     141                 :          2 : static int check_kcmp(void)
     142                 :            : {
     143                 :          2 :         int ret = sys_kcmp(getpid(), -1, -1, -1, -1);
     144                 :            : 
     145         [ -  + ]:          2 :         if (ret != -ENOSYS)
     146                 :            :                 return 0;
     147                 :            : 
     148                 :          0 :         pr_msg("System call kcmp is not supported\n");
     149                 :          0 :         return -1;
     150                 :            : }
     151                 :            : 
     152                 :          2 : static int check_prctl(void)
     153                 :            : {
     154                 :          2 :         unsigned long user_auxv = 0;
     155                 :            :         unsigned int *tid_addr;
     156                 :            :         int ret;
     157                 :            : 
     158                 :          2 :         ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long)&tid_addr, 0, 0, 0);
     159         [ -  + ]:          2 :         if (ret) {
     160                 :          0 :                 pr_msg("prctl: PR_GET_TID_ADDRESS is not supported\n");
     161                 :          0 :                 return -1;
     162                 :            :         }
     163                 :            : 
     164                 :          2 :         ret = sys_prctl(PR_SET_MM, PR_SET_MM_BRK, sys_brk(0), 0, 0);
     165         [ -  + ]:          2 :         if (ret) {
     166         [ #  # ]:          0 :                 if (ret == -EPERM)
     167                 :          0 :                         pr_msg("prctl: One needs CAP_SYS_RESOURCE capability to perform testing\n");
     168                 :            :                 else
     169                 :          0 :                         pr_msg("prctl: PR_SET_MM is not supported\n");
     170                 :            :                 return -1;
     171                 :            :         }
     172                 :            : 
     173                 :          2 :         ret = sys_prctl(PR_SET_MM, PR_SET_MM_EXE_FILE, -1, 0, 0);
     174         [ -  + ]:          2 :         if (ret != -EBADF) {
     175                 :          0 :                 pr_msg("prctl: PR_SET_MM_EXE_FILE is not supported (%d)\n", ret);
     176                 :          0 :                 return -1;
     177                 :            :         }
     178                 :            : 
     179                 :          2 :         ret = sys_prctl(PR_SET_MM, PR_SET_MM_AUXV, (long)&user_auxv, sizeof(user_auxv), 0);
     180         [ -  + ]:          2 :         if (ret) {
     181                 :          0 :                 pr_msg("prctl: PR_SET_MM_AUXV is not supported\n");
     182                 :          0 :                 return -1;
     183                 :            :         }
     184                 :            : 
     185                 :            :         return 0;
     186                 :            : }
     187                 :            : 
     188                 :            : static int check_fcntl(void)
     189                 :            : {
     190                 :            :         /*
     191                 :            :          * FIXME Add test for F_GETOWNER_UIDS once
     192                 :            :          * it's merged into mainline and kernel part
     193                 :            :          * settle down.
     194                 :            :          */
     195                 :            :         return 0;
     196                 :            : }
     197                 :            : 
     198                 :          2 : static int check_proc_stat(void)
     199                 :            : {
     200                 :            :         struct proc_pid_stat stat;
     201                 :            :         int ret;
     202                 :            : 
     203                 :          2 :         ret = parse_pid_stat(getpid(), &stat);
     204         [ -  + ]:          2 :         if (ret) {
     205                 :          0 :                 pr_msg("procfs: stat extension is not supported\n");
     206                 :          0 :                 return -1;
     207                 :            :         }
     208                 :            : 
     209                 :            :         return 0;
     210                 :            : }
     211                 :            : 
     212                 :          2 : static int check_one_fdinfo(union fdinfo_entries *e, void *arg)
     213                 :            : {
     214                 :          2 :         *(int *)arg = (int)e->efd.counter;
     215                 :          2 :         return 0;
     216                 :            : }
     217                 :            : 
     218                 :          2 : static int check_fdinfo_eventfd(void)
     219                 :            : {
     220                 :            :         int fd, ret;
     221                 :          2 :         int cnt = 13, proc_cnt = 0;
     222                 :            : 
     223                 :          2 :         fd = eventfd(cnt, 0);
     224         [ -  + ]:          2 :         if (fd < 0) {
     225                 :          0 :                 pr_perror("Can't make eventfd");
     226                 :          0 :                 return -1;
     227                 :            :         }
     228                 :            : 
     229                 :          2 :         ret = parse_fdinfo(fd, FD_TYPES__EVENTFD, check_one_fdinfo, &proc_cnt);
     230                 :          2 :         close(fd);
     231                 :            : 
     232         [ -  + ]:          2 :         if (ret) {
     233                 :          0 :                 pr_err("Error parsing proc fdinfo\n");
     234                 :          0 :                 return -1;
     235                 :            :         }
     236                 :            : 
     237         [ -  + ]:          2 :         if (proc_cnt != cnt) {
     238                 :          0 :                 pr_err("Counter mismatch (or not met) %d want %d\n",
     239                 :            :                                 proc_cnt, cnt);
     240                 :          0 :                 return -1;
     241                 :            :         }
     242                 :            : 
     243                 :          2 :         pr_info("Eventfd fdinfo works OK (%d vs %d)\n", cnt, proc_cnt);
     244                 :          2 :         return 0;
     245                 :            : }
     246                 :            : 
     247                 :          2 : static int check_one_sfd(union fdinfo_entries *e, void *arg)
     248                 :            : {
     249                 :          2 :         return 0;
     250                 :            : }
     251                 :            : 
     252                 :          2 : int check_mnt_id(void)
     253                 :            : {
     254                 :          2 :         struct fdinfo_common fdinfo = { .mnt_id = -1 };
     255                 :            :         int ret;
     256                 :            : 
     257                 :          2 :         ret = parse_fdinfo(get_service_fd(LOG_FD_OFF), FD_TYPES__UND, NULL, &fdinfo);
     258         [ +  - ]:          2 :         if (ret < 0)
     259                 :            :                 return -1;
     260                 :            : 
     261         [ +  - ]:          2 :         if (fdinfo.mnt_id == -1) {
     262                 :          2 :                 pr_err("fdinfo doesn't contain the mnt_id field\n");
     263                 :          2 :                 return -1;
     264                 :            :         }
     265                 :            : 
     266                 :            :         return 0;
     267                 :            : }
     268                 :            : 
     269                 :          2 : static int check_fdinfo_signalfd(void)
     270                 :            : {
     271                 :            :         int fd, ret;
     272                 :            :         sigset_t mask;
     273                 :            : 
     274                 :          2 :         sigemptyset(&mask);
     275                 :          2 :         sigaddset(&mask, SIGUSR1);
     276                 :          2 :         fd = signalfd(-1, &mask, 0);
     277         [ -  + ]:          2 :         if (fd < 0) {
     278                 :          0 :                 pr_perror("Can't make signalfd");
     279                 :          0 :                 return -1;
     280                 :            :         }
     281                 :            : 
     282                 :          2 :         ret = parse_fdinfo(fd, FD_TYPES__SIGNALFD, check_one_sfd, NULL);
     283                 :          2 :         close(fd);
     284                 :            : 
     285         [ -  + ]:          2 :         if (ret) {
     286                 :          0 :                 pr_err("Error parsing proc fdinfo\n");
     287                 :          0 :                 return -1;
     288                 :            :         }
     289                 :            : 
     290                 :            :         return 0;
     291                 :            : }
     292                 :            : 
     293                 :          2 : static int check_one_epoll(union fdinfo_entries *e, void *arg)
     294                 :            : {
     295                 :          2 :         *(int *)arg = e->epl.tfd;
     296                 :          2 :         return 0;
     297                 :            : }
     298                 :            : 
     299                 :          2 : static int check_fdinfo_eventpoll(void)
     300                 :            : {
     301                 :          2 :         int efd, pfd[2], proc_fd = 0, ret = -1;
     302                 :            :         struct epoll_event ev;
     303                 :            : 
     304         [ -  + ]:          2 :         if (pipe(pfd)) {
     305                 :          0 :                 pr_perror("Can't make pipe to watch");
     306                 :          0 :                 return -1;
     307                 :            :         }
     308                 :            : 
     309                 :          2 :         efd = epoll_create(1);
     310         [ -  + ]:          2 :         if (efd < 0) {
     311                 :          0 :                 pr_perror("Can't make epoll fd");
     312                 :          0 :                 goto pipe_err;
     313                 :            :         }
     314                 :            : 
     315                 :            :         memset(&ev, 0, sizeof(ev));
     316                 :          2 :         ev.events = EPOLLIN | EPOLLOUT;
     317                 :            : 
     318         [ -  + ]:          2 :         if (epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &ev)) {
     319                 :          0 :                 pr_perror("Can't add epoll tfd");
     320                 :          0 :                 goto epoll_err;
     321                 :            :         }
     322                 :            : 
     323                 :          2 :         ret = parse_fdinfo(efd, FD_TYPES__EVENTPOLL, check_one_epoll, &proc_fd);
     324         [ -  + ]:          2 :         if (ret) {
     325                 :          0 :                 pr_err("Error parsing proc fdinfo\n");
     326                 :          0 :                 goto epoll_err;
     327                 :            :         }
     328                 :            : 
     329         [ -  + ]:          2 :         if (pfd[0] != proc_fd) {
     330                 :          0 :                 pr_err("TFD mismatch (or not met) %d want %d\n",
     331                 :            :                                 proc_fd, pfd[0]);
     332                 :            :                 ret = -1;
     333                 :          0 :                 goto epoll_err;
     334                 :            :         }
     335                 :            : 
     336                 :          2 :         pr_info("Epoll fdinfo works OK (%d vs %d)\n", pfd[0], proc_fd);
     337                 :            : 
     338                 :            : epoll_err:
     339                 :          2 :         close(efd);
     340                 :            : pipe_err:
     341                 :          2 :         close(pfd[0]);
     342                 :          2 :         close(pfd[1]);
     343                 :            : 
     344                 :          2 :         return ret;
     345                 :            : }
     346                 :            : 
     347                 :          2 : static int check_one_inotify(union fdinfo_entries *e, void *arg)
     348                 :            : {
     349                 :          2 :         *(int *)arg = e->ify.wd;
     350                 :          2 :         return 0;
     351                 :            : }
     352                 :            : 
     353                 :          2 : static int check_fdinfo_inotify(void)
     354                 :            : {
     355                 :          2 :         int ifd, wd, proc_wd = -1, ret;
     356                 :            : 
     357                 :          2 :         ifd = inotify_init1(0);
     358         [ -  + ]:          2 :         if (ifd < 0) {
     359                 :          0 :                 pr_perror("Can't make inotify fd");
     360                 :          0 :                 return -1;
     361                 :            :         }
     362                 :            : 
     363                 :          2 :         wd = inotify_add_watch(ifd, ".", IN_ALL_EVENTS);
     364         [ -  + ]:          2 :         if (wd < 0) {
     365                 :          0 :                 pr_perror("Can't add watch");
     366                 :          0 :                 close(ifd);
     367                 :          0 :                 return -1;
     368                 :            :         }
     369                 :            : 
     370                 :          2 :         ret = parse_fdinfo(ifd, FD_TYPES__INOTIFY, check_one_inotify, &proc_wd);
     371                 :          2 :         close(ifd);
     372                 :            : 
     373         [ -  + ]:          2 :         if (ret < 0) {
     374                 :          0 :                 pr_err("Error parsing proc fdinfo\n");
     375                 :          0 :                 return -1;
     376                 :            :         }
     377                 :            : 
     378         [ -  + ]:          2 :         if (wd != proc_wd) {
     379                 :          0 :                 pr_err("WD mismatch (or not met) %d want %d\n", proc_wd, wd);
     380                 :          0 :                 return -1;
     381                 :            :         }
     382                 :            : 
     383                 :          2 :         pr_info("Inotify fdinfo works OK (%d vs %d)\n", wd, proc_wd);
     384                 :          2 :         return 0;
     385                 :            : }
     386                 :            : 
     387                 :          2 : static int check_fdinfo_ext(void)
     388                 :            : {
     389                 :            :         int ret = 0;
     390                 :            : 
     391                 :          2 :         ret |= check_fdinfo_eventfd();
     392                 :          2 :         ret |= check_fdinfo_eventpoll();
     393                 :          2 :         ret |= check_fdinfo_signalfd();
     394                 :          2 :         ret |= check_fdinfo_inotify();
     395                 :            : 
     396                 :          2 :         return ret;
     397                 :            : }
     398                 :            : 
     399                 :          2 : static int check_unaligned_vmsplice(void)
     400                 :            : {
     401                 :            :         int p[2], ret;
     402                 :            :         char buf; /* :) */
     403                 :            :         struct iovec iov;
     404                 :            : 
     405                 :          2 :         ret = pipe(p);
     406         [ -  + ]:          2 :         if (ret < 0) {
     407                 :          0 :                 pr_perror("Can't create pipe");
     408                 :          0 :                 return ret;
     409                 :            :         }
     410                 :          2 :         iov.iov_base = &buf;
     411                 :          2 :         iov.iov_len = sizeof(buf);
     412                 :          2 :         ret = vmsplice(p[1], &iov, 1, SPLICE_F_GIFT | SPLICE_F_NONBLOCK);
     413         [ -  + ]:          2 :         if (ret < 0) {
     414                 :          0 :                 pr_perror("Unaligned vmsplice doesn't work");
     415                 :          0 :                 goto err;
     416                 :            :         }
     417                 :            : 
     418                 :          2 :         pr_info("Unaligned vmsplice works OK\n");
     419                 :            :         ret = 0;
     420                 :            : err:
     421                 :          2 :         close(p[0]);
     422                 :          2 :         close(p[1]);
     423                 :            : 
     424                 :          2 :         return ret;
     425                 :            : }
     426                 :            : 
     427                 :            : #ifndef SO_GET_FILTER
     428                 :            : #define SO_GET_FILTER           SO_ATTACH_FILTER
     429                 :            : #endif
     430                 :            : 
     431                 :          2 : static int check_so_gets(void)
     432                 :            : {
     433                 :            :         int sk, ret = -1;
     434                 :            :         socklen_t len;
     435                 :            :         char name[IFNAMSIZ];
     436                 :            : 
     437                 :          2 :         sk = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     438         [ -  + ]:          2 :         if (sk < 0) {
     439                 :          0 :                 pr_perror("No socket");
     440                 :          0 :                 return -1;
     441                 :            :         }
     442                 :            : 
     443                 :          2 :         len = 0;
     444         [ -  + ]:          2 :         if (getsockopt(sk, SOL_SOCKET, SO_GET_FILTER, NULL, &len)) {
     445                 :          0 :                 pr_perror("Can't get socket filter");
     446                 :          0 :                 goto err;
     447                 :            :         }
     448                 :            : 
     449                 :          2 :         len = sizeof(name);
     450         [ -  + ]:          2 :         if (getsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, name, &len)) {
     451                 :          0 :                 pr_perror("Can't get socket bound dev");
     452                 :          0 :                 goto err;
     453                 :            :         }
     454                 :            : 
     455                 :            :         ret = 0;
     456                 :            : err:
     457                 :          2 :         close(sk);
     458                 :          2 :         return ret;
     459                 :            : }
     460                 :            : 
     461                 :          2 : static int check_ipc(void)
     462                 :            : {
     463                 :            :         int ret;
     464                 :            : 
     465                 :          2 :         ret = access("/proc/sys/kernel/sem_next_id", R_OK | W_OK);
     466         [ -  + ]:          2 :         if (!ret)
     467                 :            :                 return 0;
     468                 :            : 
     469                 :          0 :         pr_msg("/proc/sys/kernel/sem_next_id sysctl is missing.\n");
     470                 :          0 :         return -1;
     471                 :            : }
     472                 :            : 
     473                 :          2 : int check_sigqueuinfo()
     474                 :            : {
     475                 :          2 :         siginfo_t info = { .si_code = 1 };
     476                 :            : 
     477                 :          2 :         signal(SIGUSR1, SIG_IGN);
     478                 :            : 
     479         [ -  + ]:          2 :         if (sys_rt_sigqueueinfo(getpid(), SIGUSR1, &info)) {
     480                 :          0 :                 pr_perror("Unable to send siginfo with positive si_code to itself");
     481                 :          0 :                 return -1;
     482                 :            :         }
     483                 :            : 
     484                 :            :         return 0;
     485                 :            : }
     486                 :            : 
     487                 :          2 : int check_ptrace_peeksiginfo()
     488                 :            : {
     489                 :            :         struct ptrace_peeksiginfo_args arg;
     490                 :            :         siginfo_t siginfo;
     491                 :            :         pid_t pid, ret = 0;
     492                 :            :         k_rtsigset_t mask;
     493                 :            : 
     494                 :          2 :         pid = fork();
     495         [ -  + ]:          2 :         if (pid < 0)
     496                 :          0 :                 pr_perror("fork");
     497         [ -  + ]:          2 :         else if (pid == 0) {
     498                 :            :                 while (1)
     499                 :          0 :                         sleep(1000);
     500                 :            :                 exit(1);
     501                 :            :         }
     502                 :            : 
     503         [ +  - ]:          2 :         if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
     504                 :            :                 return -1;
     505                 :            : 
     506                 :          2 :         waitpid(pid, NULL, 0);
     507                 :            : 
     508                 :          2 :         arg.flags = 0;
     509                 :          2 :         arg.off = 0;
     510                 :          2 :         arg.nr = 1;
     511                 :            : 
     512         [ -  + ]:          2 :         if (ptrace(PTRACE_PEEKSIGINFO, pid, &arg, &siginfo) != 0) {
     513                 :          0 :                 pr_perror("Unable to dump pending signals");
     514                 :            :                 ret = -1;
     515                 :            :         }
     516                 :            : 
     517         [ -  + ]:          2 :         if (ptrace(PTRACE_GETSIGMASK, pid, sizeof(mask), &mask) != 0) {
     518                 :          0 :                 pr_perror("Unable to dump signal blocking mask");
     519                 :            :                 ret = -1;
     520                 :            :         }
     521                 :            : 
     522                 :          2 :         ptrace(PTRACE_KILL, pid, NULL, NULL);
     523                 :            : 
     524                 :          2 :         return ret;
     525                 :            : }
     526                 :            : 
     527                 :          2 : static int check_mem_dirty_track(void)
     528                 :            : {
     529         [ +  - ]:          2 :         if (kerndat_get_dirty_track() < 0)
     530                 :            :                 return -1;
     531                 :            : 
     532         [ -  + ]:          2 :         if (!kerndat_has_dirty_track)
     533                 :          0 :                 pr_warn("Dirty tracking is OFF. Memory snapshot will not work.\n");
     534                 :            :         return 0;
     535                 :            : }
     536                 :            : 
     537                 :          2 : static int check_posix_timers(void)
     538                 :            : {
     539                 :            :         int ret;
     540                 :            : 
     541                 :          2 :         ret = access("/proc/self/timers", R_OK);
     542         [ -  + ]:          2 :         if (!ret)
     543                 :            :                 return 0;
     544                 :            : 
     545                 :          0 :         pr_msg("/proc/<pid>/timers file is missing.\n");
     546                 :          0 :         return -1;
     547                 :            : }
     548                 :            : 
     549                 :          2 : int cr_check(void)
     550                 :            : {
     551                 :          2 :         struct ns_id ns = { .pid = getpid(), .nd = &mnt_ns_desc };
     552                 :            :         int ret = 0;
     553                 :            : 
     554                 :          2 :         log_set_loglevel(LOG_WARN);
     555                 :            : 
     556         [ +  - ]:          2 :         if (!is_root_user())
     557                 :            :                 return -1;
     558                 :            : 
     559                 :          2 :         root_item = alloc_pstree_item();
     560         [ +  - ]:          2 :         if (root_item == NULL)
     561                 :            :                 return -1;
     562                 :            : 
     563                 :          2 :         root_item->pid.real = getpid();
     564                 :            : 
     565         [ +  - ]:          2 :         if (collect_pstree_ids())
     566                 :            :                 return -1;
     567                 :            : 
     568                 :          2 :         ns.id = root_item->ids->mnt_ns_id;
     569                 :            : 
     570                 :          2 :         mntinfo = collect_mntinfo(&ns);
     571         [ +  - ]:          2 :         if (mntinfo == NULL)
     572                 :            :                 return -1;
     573                 :            : 
     574                 :          2 :         ret |= check_map_files();
     575                 :          2 :         ret |= check_sock_diag();
     576                 :          2 :         ret |= check_ns_last_pid();
     577                 :          2 :         ret |= check_sock_peek_off();
     578                 :          2 :         ret |= check_kcmp();
     579                 :          2 :         ret |= check_prctl();
     580                 :            :         ret |= check_fcntl();
     581                 :          2 :         ret |= check_proc_stat();
     582                 :          2 :         ret |= check_tcp();
     583                 :          2 :         ret |= check_fdinfo_ext();
     584                 :          2 :         ret |= check_unaligned_vmsplice();
     585                 :          2 :         ret |= check_tty();
     586                 :          2 :         ret |= check_so_gets();
     587                 :          2 :         ret |= check_ipc();
     588                 :          2 :         ret |= check_sigqueuinfo();
     589                 :          2 :         ret |= check_ptrace_peeksiginfo();
     590                 :          2 :         ret |= check_mem_dirty_track();
     591                 :          2 :         ret |= check_posix_timers();
     592                 :          2 :         ret |= check_tun();
     593                 :          2 :         ret |= check_mnt_id();
     594                 :            : 
     595         [ -  + ]:          2 :         if (!ret)
     596                 :          0 :                 pr_msg("Looks good.\n");
     597                 :            : 
     598                 :          2 :         return ret;
     599                 :            : }

Generated by: LCOV version 1.9