Provided by: libseccomp-dev_2.5.1-1ubuntu1~16.04.1_amd64 bug

NAME

       seccomp_rule_add, seccomp_rule_add_exact - Add a seccomp filter rule

SYNOPSIS

       #include <seccomp.h>

       typedef void * scmp_filter_ctx;

       int SCMP_SYS(syscall_name);

       struct scmp_arg_cmp SCMP_CMP(unsigned int arg,
                                    enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A0(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A1(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A2(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A3(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A4(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A5(enum scmp_compare op, ...);

       struct scmp_arg_cmp SCMP_CMP64(unsigned int arg,
                                    enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A0_64(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A1_64(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A2_64(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A3_64(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A4_64(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A5_64(enum scmp_compare op, ...);

       struct scmp_arg_cmp SCMP_CMP32(unsigned int arg,
                                    enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A0_32(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A1_32(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A2_32(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A3_32(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A4_32(enum scmp_compare op, ...);
       struct scmp_arg_cmp SCMP_A5_32(enum scmp_compare op, ...);

       int seccomp_rule_add(scmp_filter_ctx ctx, uint32_t action,
                            int syscall, unsigned int arg_cnt, ...);
       int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action,
                                  int syscall, unsigned int arg_cnt, ...);

       int seccomp_rule_add_array(scmp_filter_ctx ctx,
                                  uint32_t action, int syscall,
                                  unsigned int arg_cnt,
                                  const struct scmp_arg_cmp *arg_array);
       int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
                                        uint32_t action, int syscall,
                                        unsigned int arg_cnt,
                                        const struct scmp_arg_cmp *arg_array);

       Link with -lseccomp.

DESCRIPTION

       The        seccomp_rule_add(),        seccomp_rule_add_array(),       seccomp_rule_add_exact(),       and
       seccomp_rule_add_exact_array() functions all add a new filter rule to the current  seccomp  filter.   The
       seccomp_rule_add()  and  seccomp_rule_add_array()  functions will make a "best effort" to add the rule as
       specified, but may alter the rule slightly due to architecture  specifics  (e.g.  internal  rewriting  of
       multiplexed  syscalls,  like  socket  and  ipc  functions  on  x86).   The  seccomp_rule_add_exact()  and
       seccomp_rule_add_exact_array() functions will attempt to add the rule exactly  as  specified  so  it  may
       behave  differently  on  different  architectures.   While  it does not guarantee a exact filter ruleset,
       seccomp_rule_add() and  seccomp_rule_add_array()  do  guarantee  the  same  behavior  regardless  of  the
       architecture.

       The  newly added filter rule does not take effect until the entire filter is loaded into the kernel using
       seccomp_load(3).  When adding rules to a filter, it is important to consider  the  impact  of  previously
       loaded filters; see the seccomp_load(3) documentation for more information.

       All  of  the  filter rules supplied by the calling application are combined into a union, with additional
       logic to eliminate redundant syscall filters.  For example, if a rule  is  added  which  allows  a  given
       syscall  with  a  specific set of argument values and later a rule is added which allows the same syscall
       regardless the argument values then the first, more specific rule, is effectively dropped from the filter
       by the second more generic rule.

       The  SCMP_CMP(),  SCMP_CMP64(),  SCMP_A{0-5}(),  and  SCMP_A{0-5}_64()  macros  generate  a  scmp_arg_cmp
       structure for use with the above functions. The SCMP_CMP() and SCMP_CMP64() macros allows the  caller  to
       specify  an  arbitrary  argument along with the comparison operator, 64-bit mask, and 64-bit datum values
       where the SCMP_A{0-5}() and SCMP_A{0-5}_64() macros are specific to a certain argument.

       The SCMP_CMP32() and SCMP_A{0-5}_32() macros are similar to the variants above, but they take 32-bit mask
       and 32-bit datum values.

       It  is  recommended that whenever possible developers avoid using the SCMP_CMP() and SCMP_A{0-5}() macros
       and use the variants which are explicitly 32 or 64-bit.  This should help eliminate problems caused by an
       unwanted sign extension of negative datum values.

       If  syscall argument comparisons are included in the filter rule, all of the comparisons must be true for
       the rule to match.

       When adding syscall argument comparisons to the filter it is important  to  remember  that  while  it  is
       possible  to  have  multiple  comparisons  in a single rule, you can only compare each argument once in a
       single rule.  In other words, you can not have multiple comparisons of the  3rd  syscall  argument  in  a
       single rule.

       In  a  filter  containing  multiple architectures, it is an error to add a filter rule for a syscall that
       does not exist in all of the filter's architectures.

       While it is possible to specify the syscall value directly using the  standard  __NR_syscall  values,  in
       order  to  ensure  proper  operation  across  multiple  architectures it is highly recommended to use the
       SCMP_SYS() macro instead.  See the EXAMPLES section  below.   It  is  also  important  to  remember  that
       regardless  of  the  architectures  present  in  the filter, the syscall numbers used in filter rules are
       interpreted in the context of the native architecture.

       Starting with Linux v4.8, there may be a need to create a rule with  a  syscall  value  of  -1  to  allow
       tracing  programs  to  skip a syscall invocation; in order to create a rule with a -1 syscall value it is
       necessary  to  first  set  the  SCMP_FLTATR_API_TSKIP  attribute.   See  seccomp_attr_set(3)   for   more
       information.

       The filter context ctx is the value returned by the call to seccomp_init(3).

       Valid action values are as follows:

       SCMP_ACT_KILL
              The thread will be killed by the kernel when it calls a syscall that matches the filter rule.

       SCMP_ACT_KILL_PROCESS
              The process will be killed by the kernel when it calls a syscall that matches the filter rule.

       SCMP_ACT_TRAP
              The thread will throw a SIGSYS signal when it calls a syscall that matches the filter rule.

       SCMP_ACT_ERRNO(uint16_t errno)
              The  thread  will  receive a return value of errno when it calls a syscall that matches the filter
              rule.

       SCMP_ACT_TRACE(uint16_t msg_num)
              If the thread is being traced and the tracing process specified the  PTRACE_O_TRACESECCOMP  option
              in the call to ptrace(2), the tracing process will be notified, via PTRACE_EVENT_SECCOMP , and the
              value provided in msg_num can be retrieved using the PTRACE_GETEVENTMSG option.

       SCMP_ACT_LOG
              The seccomp filter will have no effect on the thread calling the syscall if it matches the  filter
              rule but the syscall will be logged.

       SCMP_ACT_ALLOW
              The  seccomp filter will have no effect on the thread calling the syscall if it matches the filter
              rule.

       SCMP_ACT_NOTIFY
              A monitoring process will be notified when a process running the seccomp filter  calls  a  syscall
              that  matches the filter rule.  The process that invokes the syscall waits in the kernel until the
              monitoring process has responded via seccomp_notify_respond(3) .

              When a filter utilizing SCMP_ACT_NOTIFY  is  loaded  into  the  kernel,  the  kernel  generates  a
              notification  fd  that  must  be  used  to  communicate  between  the  monitoring  process and the
              process(es) being filtered.  See seccomp_notif_fd(3) for more information.

       Valid comparison op values are as follows:

       SCMP_CMP_NE
              Matches when the argument value is not equal to the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_NE , datum )

       SCMP_CMP_LT
              Matches when the argument value is less than the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_LT , datum )

       SCMP_CMP_LE
              Matches when the argument value is less than or equal to the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_LE , datum )

       SCMP_CMP_EQ
              Matches when the argument value is equal to the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_EQ , datum )

       SCMP_CMP_GE
              Matches when the argument value is greater than or equal to the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_GE , datum )

       SCMP_CMP_GT
              Matches when the argument value is greater than the datum value, example:

              SCMP_CMP( arg , SCMP_CMP_GT , datum )

       SCMP_CMP_MASKED_EQ
              Matches when the masked argument value is equal to the masked datum value, example:

              SCMP_CMP( arg , SCMP_CMP_MASKED_EQ , mask , datum )

RETURN VALUE

       The SCMP_SYS() macro returns a value suitable for use as the syscall  value  in  the  seccomp_rule_add*()
       functions.   In  a  similar manner, the SCMP_CMP() and SCMP_A*() macros return values suitable for use as
       argument comparisons in the seccomp_rule_add() and seccomp_rule_add_exact() functions.

       The       seccomp_rule_add(),       seccomp_rule_add_array(),        seccomp_rule_add_exact(),        and
       seccomp_rule_add_exact_array()  functions  return  zero on success or one of the following error codes on
       failure:

       -EDOM  Architecture specific failure.

       -EEXIST
              The rule already exists.

       -EFAULT
              Internal libseccomp failure.

       -EINVAL
              Invalid input, either the context or architecture token is invalid.

       -ENOMEM
              The library was unable to allocate enough memory.

       -EOPNOTSUPP
              The library doesn't support the particular operation.

EXAMPLES

       #include <fcntl.h>
       #include <seccomp.h>
       #include <sys/stat.h>
       #include <sys/types.h>
       #include <stddef.h>

       #define BUF_SIZE    256

       int main(int argc, char *argv[])
       {
            int rc = -1;
            scmp_filter_ctx ctx;
            struct scmp_arg_cmp arg_cmp[] = { SCMP_A0(SCMP_CMP_EQ, 2) };
            int fd;
            unsigned char buf[BUF_SIZE];

            ctx = seccomp_init(SCMP_ACT_KILL);
            if (ctx == NULL)
                 goto out;

            /* ... */

            fd = open("file.txt", 0);

            /* ... */

            rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
            if (rc < 0)
                 goto out;

            rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
            if (rc < 0)
                 goto out;

            rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
            if (rc < 0)
                 goto out;

            rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
                            SCMP_A0(SCMP_CMP_EQ, fd),
                            SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buf),
                            SCMP_A2(SCMP_CMP_LE, BUF_SIZE));
            if (rc < 0)
                 goto out;

            rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
                            SCMP_CMP(0, SCMP_CMP_EQ, fd));
            if (rc < 0)
                 goto out;

            rc = seccomp_rule_add_array(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
                                  arg_cmp);
            if (rc < 0)
                 goto out;

            rc = seccomp_load(ctx);
            if (rc < 0)
                 goto out;

            /* ... */

       out:
            seccomp_release(ctx);
            return -rc;
       }

NOTES

       While the seccomp filter can be generated independent of the kernel, kernel support is required  to  load
       and enforce the seccomp filter generated by libseccomp.

       The  libseccomp  project  site,  with  more  information  and the source code repository, can be found at
       https://github.com/seccomp/libseccomp.  This tool, as well as the libseccomp library, is currently  under
       development, please report any bugs at the project site or directly to the author.

AUTHOR

       Paul Moore <paul@paul-moore.com>

SEE ALSO

       seccomp_syscall_resolve_name_rewrite(3),           seccomp_syscall_priority(3),          seccomp_load(3),
       seccomp_attr_set(3)