"Fossies" - the Fresh Open Source Software Archive

Member "file-5.35/src/seccomp.c" (11 Sep 2018, 6398 Bytes) of package /linux/misc/file-5.35.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "seccomp.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.34_vs_5.35.

    1 /*
    2  * Redistribution and use in source and binary forms, with or without
    3  * modification, are permitted provided that the following conditions
    4  * are met:
    5  * 1. Redistributions of source code must retain the above copyright
    6  *    notice immediately at the beginning of the file, without modification,
    7  *    this list of conditions, and the following disclaimer.
    8  * 2. Redistributions in binary form must reproduce the above copyright
    9  *    notice, this list of conditions and the following disclaimer in the
   10  *    documentation and/or other materials provided with the distribution.
   11  *
   12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   13  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   14  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   15  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   16  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   17  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   18  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   19  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   20  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   21  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   22  * SUCH DAMAGE.
   23  */
   24 /*
   25  * libseccomp hooks.
   26  */
   27 #include "file.h"
   28 
   29 #ifndef lint
   30 FILE_RCSID("@(#)$File: seccomp.c,v 1.7 2018/09/09 20:33:28 christos Exp $")
   31 #endif  /* lint */
   32 
   33 #if HAVE_LIBSECCOMP
   34 #include <seccomp.h> /* libseccomp */
   35 #include <sys/prctl.h> /* prctl */
   36 #include <sys/socket.h>
   37 #include <fcntl.h>
   38 #include <stdlib.h>
   39 #include <errno.h>
   40 
   41 #define DENY_RULE(call) \
   42     do \
   43     if (seccomp_rule_add (ctx, SCMP_ACT_KILL, SCMP_SYS(call), 0) == -1) \
   44         goto out; \
   45     while (/*CONSTCOND*/0)
   46 #define ALLOW_RULE(call) \
   47     do \
   48     if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(call), 0) == -1) \
   49         goto out; \
   50     while (/*CONSTCOND*/0)
   51 
   52 static scmp_filter_ctx ctx;
   53 
   54 
   55 int
   56 enable_sandbox_basic(void)
   57 {
   58 
   59     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
   60         return -1;
   61 
   62     if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
   63         return -1;
   64 
   65     // initialize the filter
   66     ctx = seccomp_init(SCMP_ACT_ALLOW);
   67     if (ctx == NULL)
   68         return 1;
   69 
   70     DENY_RULE(_sysctl);
   71     DENY_RULE(acct);
   72     DENY_RULE(add_key);
   73     DENY_RULE(adjtimex);
   74     DENY_RULE(chroot);
   75     DENY_RULE(clock_adjtime);
   76     DENY_RULE(create_module);
   77     DENY_RULE(delete_module);
   78     DENY_RULE(fanotify_init);
   79     DENY_RULE(finit_module);
   80     DENY_RULE(get_kernel_syms);
   81     DENY_RULE(get_mempolicy);
   82     DENY_RULE(init_module);
   83     DENY_RULE(io_cancel);
   84     DENY_RULE(io_destroy);
   85     DENY_RULE(io_getevents);
   86     DENY_RULE(io_setup);
   87     DENY_RULE(io_submit);
   88     DENY_RULE(ioperm);
   89     DENY_RULE(iopl);
   90     DENY_RULE(ioprio_set);
   91     DENY_RULE(kcmp);
   92 #ifdef __NR_kexec_file_load
   93     DENY_RULE(kexec_file_load);
   94 #endif
   95     DENY_RULE(kexec_load);
   96     DENY_RULE(keyctl);
   97     DENY_RULE(lookup_dcookie);
   98     DENY_RULE(mbind);
   99     DENY_RULE(nfsservctl);
  100     DENY_RULE(migrate_pages);
  101     DENY_RULE(modify_ldt);
  102     DENY_RULE(mount);
  103     DENY_RULE(move_pages);
  104     DENY_RULE(name_to_handle_at);
  105     DENY_RULE(open_by_handle_at);
  106     DENY_RULE(perf_event_open);
  107     DENY_RULE(pivot_root);
  108     DENY_RULE(process_vm_readv);
  109     DENY_RULE(process_vm_writev);
  110     DENY_RULE(ptrace);
  111     DENY_RULE(reboot);
  112     DENY_RULE(remap_file_pages);
  113     DENY_RULE(request_key);
  114     DENY_RULE(set_mempolicy);
  115     DENY_RULE(swapoff);
  116     DENY_RULE(swapon);
  117     DENY_RULE(sysfs);
  118     DENY_RULE(syslog);
  119     DENY_RULE(tuxcall);
  120     DENY_RULE(umount2);
  121     DENY_RULE(uselib);
  122     DENY_RULE(vmsplice);
  123 
  124     // blocking dangerous syscalls that file should not need
  125     DENY_RULE (execve);
  126     DENY_RULE (socket);
  127     // ...
  128 
  129 
  130     // applying filter...
  131     if (seccomp_load (ctx) == -1)
  132         goto out;
  133     // free ctx after the filter has been loaded into the kernel
  134     seccomp_release(ctx);
  135     return 0;
  136 
  137 out:
  138     seccomp_release(ctx);
  139     return -1;
  140 }
  141 
  142 
  143 int
  144 enable_sandbox_full(void)
  145 {
  146 
  147     // prevent child processes from getting more priv e.g. via setuid,
  148     // capabilities, ...
  149     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
  150         return -1;
  151 
  152     if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
  153         return -1;
  154 
  155     // initialize the filter
  156     ctx = seccomp_init(SCMP_ACT_KILL);
  157     if (ctx == NULL)
  158         return -1;
  159 
  160     ALLOW_RULE(access);
  161     ALLOW_RULE(brk);
  162     ALLOW_RULE(close);
  163     ALLOW_RULE(dup2);
  164     ALLOW_RULE(exit);
  165     ALLOW_RULE(exit_group);
  166     ALLOW_RULE(fcntl);
  167     ALLOW_RULE(fcntl64);
  168     ALLOW_RULE(fstat);
  169     ALLOW_RULE(fstat64);
  170     ALLOW_RULE(getdents);
  171 #ifdef __NR_getdents64
  172     ALLOW_RULE(getdents64);
  173 #endif
  174     ALLOW_RULE(ioctl);
  175     ALLOW_RULE(lseek);
  176     ALLOW_RULE(_llseek);
  177     ALLOW_RULE(lstat);
  178     ALLOW_RULE(lstat64);
  179     ALLOW_RULE(mmap);
  180     ALLOW_RULE(mmap2);
  181     ALLOW_RULE(mprotect);
  182     ALLOW_RULE(mremap);
  183     ALLOW_RULE(munmap);
  184 #ifdef __NR_newfstatat
  185     ALLOW_RULE(newfstatat);
  186 #endif
  187     ALLOW_RULE(open);
  188     ALLOW_RULE(openat);
  189     ALLOW_RULE(pread64);
  190     ALLOW_RULE(read);
  191     ALLOW_RULE(readlink);
  192     ALLOW_RULE(rt_sigaction);
  193     ALLOW_RULE(rt_sigprocmask);
  194     ALLOW_RULE(rt_sigreturn);
  195     ALLOW_RULE(select);
  196     ALLOW_RULE(stat);
  197     ALLOW_RULE(stat64);
  198     ALLOW_RULE(sysinfo);
  199     ALLOW_RULE(unlink);
  200     ALLOW_RULE(write);
  201 
  202 
  203 #if 0
  204     // needed by valgrind
  205     ALLOW_RULE(gettid);
  206     ALLOW_RULE(getpid);
  207     ALLOW_RULE(rt_sigtimedwait);
  208 #endif
  209 
  210 #if 0
  211      /* special restrictions for socket, only allow AF_UNIX/AF_LOCAL */
  212      if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
  213          SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) == -1)
  214         goto out;
  215 
  216      if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
  217          SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) == -1)
  218         goto out;
  219 
  220 
  221      /* special restrictions for open, prevent opening files for writing */
  222      if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
  223          SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) == -1)
  224         goto out;
  225 
  226      if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
  227          SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) == -1)
  228         goto out;
  229 
  230      if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
  231          SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) == -1)
  232         goto out;
  233 
  234 
  235      /* allow stderr */
  236      if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
  237          SCMP_CMP(0, SCMP_CMP_EQ, 2)) == -1)
  238          goto out;
  239 #endif
  240 
  241     // applying filter...
  242     if (seccomp_load(ctx) == -1)
  243         goto out;
  244     // free ctx after the filter has been loaded into the kernel
  245     seccomp_release(ctx);
  246     return 0;
  247 
  248 out:
  249     // something went wrong
  250     seccomp_release(ctx);
  251     return -1;
  252 }
  253 #endif