github.com/rigado/snapd@v2.42.5-go-mod+incompatible/cmd/snap-confine/seccomp-support-ext.c (about)

     1  /*
     2   * Copyright (C) 2019 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  #ifdef HAVE_CONFIG_H
    18  #include "config.h"
    19  #endif
    20  
    21  #include "seccomp-support-ext.h"
    22  
    23  #include <errno.h>
    24  #include <linux/seccomp.h>
    25  #include <stdio.h>
    26  #include <sys/prctl.h>
    27  #include <sys/syscall.h>
    28  #include <sys/types.h>
    29  #include <unistd.h>
    30  
    31  #include "../libsnap-confine-private/utils.h"
    32  
    33  #ifndef SECCOMP_FILTER_FLAG_LOG
    34  #define SECCOMP_FILTER_FLAG_LOG 2
    35  #endif
    36  
    37  #ifndef seccomp
    38  // prototype because we build with -Wstrict-prototypes
    39  int seccomp(unsigned int operation, unsigned int flags, void *args);
    40  
    41  int seccomp(unsigned int operation, unsigned int flags, void *args) {
    42      errno = 0;
    43      return syscall(__NR_seccomp, operation, flags, args);
    44  }
    45  #endif
    46  
    47  size_t sc_read_seccomp_filter(const char *filename, char *buf, size_t buf_size) {
    48      FILE *file = fopen(filename, "rb");
    49      if (file == NULL) {
    50          die("cannot open seccomp filter %s", filename);
    51      }
    52      size_t num_read = fread(buf, 1, buf_size, file);
    53      if (ferror(file) != 0) {
    54          die("cannot read seccomp profile %s", filename);
    55      }
    56      if (feof(file) == 0) {
    57          die("cannot fit seccomp profile %s to memory buffer", filename);
    58      }
    59      fclose(file);
    60      debug("read %zu bytes from %s", num_read, filename);
    61      return num_read;
    62  }
    63  
    64  void sc_apply_seccomp_filter(struct sock_fprog *prog) {
    65      int err;
    66  
    67      // Load filter into the kernel (by this point we have dropped to the
    68      // calling user but still retain CAP_SYS_ADMIN).
    69      //
    70      // Importantly we are intentionally *not* setting NO_NEW_PRIVS because it
    71      // interferes with exec transitions in AppArmor with certain snapd
    72      // interfaces. Not setting NO_NEW_PRIVS does mean that applications can
    73      // adjust their sandbox if they have CAP_SYS_ADMIN or, if running on < 4.8
    74      // kernels, break out of the seccomp via ptrace. Both CAP_SYS_ADMIN and
    75      // 'ptrace (trace)' are blocked by AppArmor with typical snapd interfaces.
    76      err = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, prog);
    77      if (err != 0) {
    78          /* The profile may fail to load using the "modern" interface.
    79           * In such case use the older prctl-based interface instead. */
    80          switch (errno) {
    81              case ENOSYS:
    82                  debug("kernel doesn't support the seccomp(2) syscall");
    83                  break;
    84              case EINVAL:
    85                  debug("kernel may not support the SECCOMP_FILTER_FLAG_LOG flag");
    86                  break;
    87          }
    88          debug("falling back to prctl(2) syscall to load seccomp filter");
    89          err = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
    90          if (err != 0) {
    91              die("cannot apply seccomp profile");
    92          }
    93      }
    94  }