seccomp-tools 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -1
- data/ext/ptrace/extconf.rb +2 -0
- data/ext/ptrace/ptrace.c +43 -0
- data/lib/seccomp-tools/asm/asm.rb +1 -1
- data/lib/seccomp-tools/asm/compiler.rb +9 -2
- data/lib/seccomp-tools/asm/tokenizer.rb +3 -2
- data/lib/seccomp-tools/bpf.rb +1 -1
- data/lib/seccomp-tools/cli/asm.rb +5 -5
- data/lib/seccomp-tools/cli/base.rb +3 -2
- data/lib/seccomp-tools/cli/dump.rb +27 -2
- data/lib/seccomp-tools/dumper.rb +55 -2
- data/lib/seccomp-tools/emulator.rb +1 -1
- data/lib/seccomp-tools/logger.rb +40 -0
- data/lib/seccomp-tools/util.rb +6 -3
- data/lib/seccomp-tools/version.rb +1 -1
- metadata +13 -26
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2726a64dc089ec7c492cedad9a98d500c656dce84ca593a505d95a42cd07906c
         | 
| 4 | 
            +
              data.tar.gz: c8d3eec04aa38ead5bac1727bb4a1a29199283e648b902edb38df2a7fc4e539f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2639ed20158afda2cc96dfeb16899f417d50180da548b4a45a0024c12119d0b9908649979fb9ab00287d41478f507eb6740ffda855aa238cd82755d774ca82de
         | 
| 7 | 
            +
              data.tar.gz: 6e6df86398ee4bde9ff9c54647dc5af95eb03e40001cf6117077afeecf20ecaed12f6e3f53b47bda1e2908094632c12e9d7faee3ee72c2422d7665016e583eff
         | 
    
        data/README.md
    CHANGED
    
    | @@ -68,6 +68,8 @@ $ seccomp-tools dump --help | |
| 68 68 | 
             
            #                                      If multiple seccomp syscalls have been invoked (see --limit),
         | 
| 69 69 | 
             
            #                                      results will be written to FILE, FILE_1, FILE_2.. etc.
         | 
| 70 70 | 
             
            #                                      For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...
         | 
| 71 | 
            +
            #     -p, --pid PID                    Dump installed seccomp filters of the existing process.
         | 
| 72 | 
            +
            #                                      You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.
         | 
| 71 73 |  | 
| 72 74 | 
             
            ```
         | 
| 73 75 |  | 
| @@ -79,7 +81,7 @@ This work is done by the `ptrace` syscall. | |
| 79 81 | 
             
            NOTICE: beware of the execution file will be executed.
         | 
| 80 82 | 
             
            ```bash
         | 
| 81 83 | 
             
            $ file spec/binary/twctf-2016-diary
         | 
| 82 | 
            -
            # spec/binary/twctf-2016-diary: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ | 
| 84 | 
            +
            # spec/binary/twctf-2016-diary: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=3648e29153ac0259a0b7c3e25537a5334f50107f, not stripped
         | 
| 83 85 |  | 
| 84 86 | 
             
            $ seccomp-tools dump spec/binary/twctf-2016-diary
         | 
| 85 87 | 
             
            #  line  CODE  JT   JF      K
         | 
| @@ -168,6 +170,7 @@ $ seccomp-tools asm | |
| 168 170 | 
             
            #                                      Default: inspect
         | 
| 169 171 | 
             
            #     -a, --arch ARCH                  Specify architecture.
         | 
| 170 172 | 
             
            #                                      Supported architectures are <amd64|i386>.
         | 
| 173 | 
            +
            #                                      Default: amd64
         | 
| 171 174 |  | 
| 172 175 | 
             
            # Input file for asm
         | 
| 173 176 | 
             
            $ cat spec/data/libseccomp.asm
         | 
| @@ -265,6 +268,7 @@ $ seccomp-tools emu --help | |
| 265 268 | 
             
            # Usage: seccomp-tools emu [options] BPF_FILE [sys_nr [arg0 [arg1 ... arg5]]]
         | 
| 266 269 | 
             
            #     -a, --arch ARCH                  Specify architecture.
         | 
| 267 270 | 
             
            #                                      Supported architectures are <amd64|i386>.
         | 
| 271 | 
            +
            #                                      Default: amd64
         | 
| 268 272 | 
             
            #     -q, --[no-]quiet                 Run quietly, only show emulation result.
         | 
| 269 273 |  | 
| 270 274 | 
             
            $ seccomp-tools emu spec/data/libseccomp.bpf write 0x3
         | 
    
        data/ext/ptrace/extconf.rb
    CHANGED
    
    
    
        data/ext/ptrace/ptrace.c
    CHANGED
    
    | @@ -1,5 +1,8 @@ | |
| 1 | 
            +
            #include <errno.h>
         | 
| 2 | 
            +
            #include <linux/filter.h>
         | 
| 1 3 | 
             
            #include <sys/ptrace.h>
         | 
| 2 4 | 
             
            #include <sys/signal.h>
         | 
| 5 | 
            +
            #include <sys/wait.h>
         | 
| 3 6 |  | 
| 4 7 | 
             
            #include "ruby.h"
         | 
| 5 8 |  | 
| @@ -50,6 +53,40 @@ ptrace_traceme_and_stop(VALUE mod) { | |
| 50 53 | 
             
              return Qnil;
         | 
| 51 54 | 
             
            }
         | 
| 52 55 |  | 
| 56 | 
            +
            static VALUE
         | 
| 57 | 
            +
            ptrace_attach_and_wait(VALUE _mod, VALUE pid) {
         | 
| 58 | 
            +
              long val = ptrace(PTRACE_ATTACH, NUM2LONG(pid), 0, 0);
         | 
| 59 | 
            +
              if(val < 0)
         | 
| 60 | 
            +
                rb_sys_fail("ptrace attach failed");
         | 
| 61 | 
            +
              waitpid(NUM2LONG(pid), NULL, 0);
         | 
| 62 | 
            +
              return Qnil;
         | 
| 63 | 
            +
            }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            static VALUE
         | 
| 66 | 
            +
            ptrace_seccomp_get_filter(VALUE _mod, VALUE pid, VALUE index) {
         | 
| 67 | 
            +
              long count = ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), NULL);
         | 
| 68 | 
            +
              struct sock_filter *filter;
         | 
| 69 | 
            +
              VALUE result;
         | 
| 70 | 
            +
              if(count < 0)
         | 
| 71 | 
            +
                rb_sys_fail("ptrace seccomp_get_filter failed");
         | 
| 72 | 
            +
              filter = ALLOC_N(struct sock_filter, count);
         | 
| 73 | 
            +
              if(ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), filter) != count) {
         | 
| 74 | 
            +
                xfree(filter);
         | 
| 75 | 
            +
                rb_sys_fail("ptrace seccomp_get_filter failed");
         | 
| 76 | 
            +
              }
         | 
| 77 | 
            +
              result = rb_str_new((const char *)filter, sizeof(struct sock_filter) * count);
         | 
| 78 | 
            +
              xfree(filter);
         | 
| 79 | 
            +
              return result;
         | 
| 80 | 
            +
            }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            static VALUE
         | 
| 83 | 
            +
            ptrace_detach(VALUE _mod, VALUE pid) {
         | 
| 84 | 
            +
              long val = ptrace(PTRACE_DETACH, NUM2LONG(pid), 0, 0);
         | 
| 85 | 
            +
              if(val < 0)
         | 
| 86 | 
            +
                rb_sys_fail(0);
         | 
| 87 | 
            +
              return Qnil;
         | 
| 88 | 
            +
            }
         | 
| 89 | 
            +
             | 
| 53 90 |  | 
| 54 91 | 
             
            void Init_ptrace(void) {
         | 
| 55 92 | 
             
              VALUE mSeccompTools = rb_define_module("SeccompTools");
         | 
| @@ -79,5 +116,11 @@ void Init_ptrace(void) { | |
| 79 116 | 
             
              rb_define_module_function(mPtrace, "traceme", ptrace_traceme, 0);
         | 
| 80 117 | 
             
              /* stop itself before parent attaching */
         | 
| 81 118 | 
             
              rb_define_module_function(mPtrace, "traceme_and_stop", ptrace_traceme_and_stop, 0);
         | 
| 119 | 
            +
              /* attach to an existing process */
         | 
| 120 | 
            +
              rb_define_module_function(mPtrace, "attach_and_wait", ptrace_attach_and_wait, 1);
         | 
| 121 | 
            +
              /* retrieve seccomp filter */
         | 
| 122 | 
            +
              rb_define_module_function(mPtrace, "seccomp_get_filter", ptrace_seccomp_get_filter, 2);
         | 
| 123 | 
            +
              /* detach from an existing process */
         | 
| 124 | 
            +
              rb_define_module_function(mPtrace, "detach", ptrace_detach, 1);
         | 
| 82 125 | 
             
            }
         | 
| 83 126 |  | 
| @@ -28,7 +28,7 @@ module SeccompTools | |
| 28 28 | 
             
                #   EOS
         | 
| 29 29 | 
             
                #   #=> <raw binary bytes>
         | 
| 30 30 | 
             
                def asm(str, arch: nil)
         | 
| 31 | 
            -
                  arch = Util.system_arch if arch.nil? | 
| 31 | 
            +
                  arch = Util.system_arch if arch.nil?
         | 
| 32 32 | 
             
                  compiler = Compiler.new(arch)
         | 
| 33 33 | 
             
                  str.lines.each { |l| compiler.process(l) }
         | 
| 34 34 | 
             
                  compiler.compile!.map(&:asm).join
         | 
| @@ -39,6 +39,7 @@ module SeccompTools | |
| 39 39 | 
             
                            when /\?/ then cmp
         | 
| 40 40 | 
             
                            when /^#{Tokenizer::LABEL_REGEXP}:/ then define_label
         | 
| 41 41 | 
             
                            when /^return/ then ret
         | 
| 42 | 
            +
                            when /^A\s*=\s*-A/ then alu_neg
         | 
| 42 43 | 
             
                            when /^(A|X)\s*=[^=]/ then assign
         | 
| 43 44 | 
             
                            when /^mem\[\d+\]\s*=\s*(A|X)/ then store
         | 
| 44 45 | 
             
                            when /^A\s*.{1,2}=/ then alu
         | 
| @@ -127,6 +128,8 @@ module SeccompTools | |
| 127 128 | 
             
                  end
         | 
| 128 129 |  | 
| 129 130 | 
             
                  def compile_alu(op, val)
         | 
| 131 | 
            +
                    return emit(:alu, :neg) if op == :neg
         | 
| 132 | 
            +
             | 
| 130 133 | 
             
                    val = evaluate(val)
         | 
| 131 134 | 
             
                    src = val == :x ? :x : :k
         | 
| 132 135 | 
             
                    val = 0 if val == :x
         | 
| @@ -146,7 +149,7 @@ module SeccompTools | |
| 146 149 | 
             
                    emit(:jmp, :ja, k: targ)
         | 
| 147 150 | 
             
                  end
         | 
| 148 151 |  | 
| 149 | 
            -
                  # Compiles  | 
| 152 | 
            +
                  # Compiles comparison.
         | 
| 150 153 | 
             
                  def compile_cmp(op, val, jt, jf)
         | 
| 151 154 | 
             
                    jt = label_offset(jt)
         | 
| 152 155 | 
             
                    jf = label_offset(jf)
         | 
| @@ -267,7 +270,6 @@ module SeccompTools | |
| 267 270 | 
             
                  end
         | 
| 268 271 |  | 
| 269 272 | 
             
                  # A op= sys_num_x
         | 
| 270 | 
            -
                  # TODO: support A = -A
         | 
| 271 273 | 
             
                  def alu
         | 
| 272 274 | 
             
                    token.fetch!('A')
         | 
| 273 275 | 
             
                    op = token.fetch!(:alu_op)
         | 
| @@ -276,6 +278,11 @@ module SeccompTools | |
| 276 278 | 
             
                    [:alu, op, src]
         | 
| 277 279 | 
             
                  end
         | 
| 278 280 |  | 
| 281 | 
            +
                  # A = -A
         | 
| 282 | 
            +
                  def alu_neg
         | 
| 283 | 
            +
                    %i[alu neg]
         | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
             | 
| 279 286 | 
             
                  def remove_comment(line)
         | 
| 280 287 | 
             
                    line = line.to_s.dup
         | 
| 281 288 | 
             
                    line.slice!(/#.*\Z/m)
         | 
| @@ -5,8 +5,9 @@ require 'seccomp-tools/instruction/alu' | |
| 5 5 |  | 
| 6 6 | 
             
            module SeccompTools
         | 
| 7 7 | 
             
              module Asm
         | 
| 8 | 
            -
                # Fetch tokens from string.
         | 
| 9 | 
            -
                # | 
| 8 | 
            +
                # Fetch tokens from a string.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # Internal used by {Compiler}.
         | 
| 10 11 | 
             
                # @private
         | 
| 11 12 | 
             
                class Tokenizer
         | 
| 12 13 | 
             
                  # a valid label
         | 
    
        data/lib/seccomp-tools/bpf.rb
    CHANGED
    
    | @@ -80,7 +80,7 @@ module SeccompTools | |
| 80 80 | 
             
                # @param [Context] context
         | 
| 81 81 | 
             
                #   Current context.
         | 
| 82 82 | 
             
                # @yieldparam [Integer] pc
         | 
| 83 | 
            -
                #   Program  | 
| 83 | 
            +
                #   Program counter after this instruction.
         | 
| 84 84 | 
             
                # @yieldparam [Context] ctx
         | 
| 85 85 | 
             
                #   Context after this instruction.
         | 
| 86 86 | 
             
                # @return [void]
         | 
| @@ -51,11 +51,11 @@ module SeccompTools | |
| 51 51 | 
             
                      when :raw then res
         | 
| 52 52 | 
             
                      when :c_array, :carray then "unsigned char bpf[] = {#{res.bytes.join(',')}};\n"
         | 
| 53 53 | 
             
                      when :c_source then SeccompTools::Util.template('asm.c').sub('<TO_BE_REPLACED>', res.bytes.join(','))
         | 
| 54 | 
            -
                      when :assembly | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 54 | 
            +
                      when :assembly
         | 
| 55 | 
            +
                        SeccompTools::Util.template("asm.#{option[:arch]}.asm").sub(
         | 
| 56 | 
            +
                          '<TO_BE_REPLACED>',
         | 
| 57 | 
            +
                          res.bytes.map { |b| format('\\\%03o', b) }.join
         | 
| 58 | 
            +
                        )
         | 
| 59 59 | 
             
                      end
         | 
| 60 60 | 
             
                    end
         | 
| 61 61 | 
             
                  end
         | 
| @@ -82,7 +82,7 @@ module SeccompTools | |
| 82 82 | 
             
                    File.join(File.dirname(file), base + suffix) + ext
         | 
| 83 83 | 
             
                  end
         | 
| 84 84 |  | 
| 85 | 
            -
                  # For  | 
| 85 | 
            +
                  # For descendants to define usage message easily.
         | 
| 86 86 | 
             
                  # @return [String]
         | 
| 87 87 | 
             
                  #   Usage information.
         | 
| 88 88 | 
             
                  def usage
         | 
| @@ -92,7 +92,8 @@ module SeccompTools | |
| 92 92 | 
             
                  def option_arch(opt)
         | 
| 93 93 | 
             
                    supported = Util.supported_archs
         | 
| 94 94 | 
             
                    opt.on('-a', '--arch ARCH', supported, 'Specify architecture.',
         | 
| 95 | 
            -
                           "Supported architectures are <#{supported.join('|')}>." | 
| 95 | 
            +
                           "Supported architectures are <#{supported.join('|')}>.",
         | 
| 96 | 
            +
                           "Default: #{Util.system_arch}") do |a|
         | 
| 96 97 | 
             
                      option[:arch] = a
         | 
| 97 98 | 
             
                    end
         | 
| 98 99 | 
             
                  end
         | 
| @@ -1,8 +1,11 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'shellwords'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            require 'seccomp-tools/cli/base'
         | 
| 4 6 | 
             
            require 'seccomp-tools/disasm/disasm'
         | 
| 5 7 | 
             
            require 'seccomp-tools/dumper'
         | 
| 8 | 
            +
            require 'seccomp-tools/logger'
         | 
| 6 9 |  | 
| 7 10 | 
             
            module SeccompTools
         | 
| 8 11 | 
             
              module CLI
         | 
| @@ -17,6 +20,7 @@ module SeccompTools | |
| 17 20 | 
             
                    super
         | 
| 18 21 | 
             
                    option[:format] = :disasm
         | 
| 19 22 | 
             
                    option[:limit] = 1
         | 
| 23 | 
            +
                    option[:pid] = nil
         | 
| 20 24 | 
             
                  end
         | 
| 21 25 |  | 
| 22 26 | 
             
                  # Define option parser.
         | 
| @@ -48,6 +52,12 @@ module SeccompTools | |
| 48 52 | 
             
                             'For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...') do |o|
         | 
| 49 53 | 
             
                               option[:ofile] = o
         | 
| 50 54 | 
             
                             end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      opt.on('-p', '--pid PID', 'Dump installed seccomp filters of the existing process.',
         | 
| 57 | 
            +
                             'You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.',
         | 
| 58 | 
            +
                             Integer) do |p|
         | 
| 59 | 
            +
                        option[:pid] = p
         | 
| 60 | 
            +
                      end
         | 
| 51 61 | 
             
                    end
         | 
| 52 62 | 
             
                  end
         | 
| 53 63 |  | 
| @@ -56,14 +66,29 @@ module SeccompTools | |
| 56 66 | 
             
                  def handle
         | 
| 57 67 | 
             
                    return unless super
         | 
| 58 68 |  | 
| 59 | 
            -
                     | 
| 60 | 
            -
                    SeccompTools::Dumper.dump('/bin/sh', '-c', option[:command], limit: option[:limit]) do |bpf, arch|
         | 
| 69 | 
            +
                    block = lambda do |bpf, arch|
         | 
| 61 70 | 
             
                      case option[:format]
         | 
| 62 71 | 
             
                      when :inspect then output { '"' + bpf.bytes.map { |b| format('\\x%02X', b) }.join + "\"\n" }
         | 
| 63 72 | 
             
                      when :raw then output { bpf }
         | 
| 64 73 | 
             
                      when :disasm then output { SeccompTools::Disasm.disasm(bpf, arch: arch) }
         | 
| 65 74 | 
             
                      end
         | 
| 66 75 | 
             
                    end
         | 
| 76 | 
            +
                    if option[:pid].nil?
         | 
| 77 | 
            +
                      option[:command] = argv.shift unless argv.empty?
         | 
| 78 | 
            +
                      SeccompTools::Dumper.dump('/bin/sh', '-c', option[:command], limit: option[:limit], &block)
         | 
| 79 | 
            +
                    else
         | 
| 80 | 
            +
                      begin
         | 
| 81 | 
            +
                        SeccompTools::Dumper.dump_by_pid(option[:pid], option[:limit], &block)
         | 
| 82 | 
            +
                      rescue Errno::EPERM, Errno::EACCES => e
         | 
| 83 | 
            +
                        Logger.error(<<~EOS)
         | 
| 84 | 
            +
                        #{e}
         | 
| 85 | 
            +
                        PTRACE_SECCOMP_GET_FILTER requires CAP_SYS_ADMIN
         | 
| 86 | 
            +
                        Try:
         | 
| 87 | 
            +
                            sudo env "PATH=$PATH" #{(%w[seccomp-tools] + ARGV).shelljoin}
         | 
| 88 | 
            +
                        EOS
         | 
| 89 | 
            +
                        exit(1)
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
                    end
         | 
| 67 92 | 
             
                  end
         | 
| 68 93 | 
             
                end
         | 
| 69 94 | 
             
              end
         | 
    
        data/lib/seccomp-tools/dumper.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'seccomp-tools/logger'
         | 
| 3 4 | 
             
            require 'seccomp-tools/ptrace'
         | 
| 4 5 | 
             
            require 'seccomp-tools/syscall'
         | 
| 5 6 |  | 
| @@ -79,6 +80,7 @@ module SeccompTools | |
| 79 80 | 
             
                      !limit.zero?
         | 
| 80 81 | 
             
                    end
         | 
| 81 82 | 
             
                    syscalls.each_key { |cpid| Process.kill('KILL', cpid) if alive?(cpid) }
         | 
| 83 | 
            +
                    Process.waitall
         | 
| 82 84 | 
             
                    collect
         | 
| 83 85 | 
             
                  end
         | 
| 84 86 |  | 
| @@ -124,10 +126,61 @@ module SeccompTools | |
| 124 126 | 
             
                    Ptrace.traceme_and_stop
         | 
| 125 127 | 
             
                    exec(*args)
         | 
| 126 128 | 
             
                  rescue # rubocop:disable Style/RescueStandardError # exec fail
         | 
| 127 | 
            -
                     | 
| 128 | 
            -
                    warn("Failed to execute #{args.join(' ')}")
         | 
| 129 | 
            +
                    Logger.error("Failed to execute #{args.join(' ')}")
         | 
| 129 130 | 
             
                    exit(1)
         | 
| 130 131 | 
             
                  end
         | 
| 131 132 | 
             
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                # Dump installed seccomp-bpf of an existing process using PTRACE_SECCOMP_GET_FILTER.
         | 
| 135 | 
            +
                #
         | 
| 136 | 
            +
                # Dump the installed seccomp-bpf from a running process. This is achieved by the ptrace command
         | 
| 137 | 
            +
                # PTRACE_SECCOMP_GET_FILTER, which needs CAP_SYS_ADMIN capability.
         | 
| 138 | 
            +
                #
         | 
| 139 | 
            +
                # @param [Integer] pid
         | 
| 140 | 
            +
                #   Target process identifier.
         | 
| 141 | 
            +
                # @param [Integer] limit
         | 
| 142 | 
            +
                #   Number of filters to dump. Negative number for unlimited.
         | 
| 143 | 
            +
                # @yieldparam [String] bpf
         | 
| 144 | 
            +
                #   Seccomp bpf in raw bytes.
         | 
| 145 | 
            +
                # @yieldparam [Symbol] arch
         | 
| 146 | 
            +
                #   Architecture of the target process (always nil right now).
         | 
| 147 | 
            +
                # @return [Array<Object>, Array<String>]
         | 
| 148 | 
            +
                #   Return the block returned. If block is not given, array of raw bytes will be returned.
         | 
| 149 | 
            +
                # @raise [Errno::ESRCH]
         | 
| 150 | 
            +
                #   Raises when the target process does not exist.
         | 
| 151 | 
            +
                # @raise [Errno::EPERM]
         | 
| 152 | 
            +
                #   Raises the error if not allowed to attach.
         | 
| 153 | 
            +
                # @raise [Errno::EACCES]
         | 
| 154 | 
            +
                #   Raises the error if not allowed to dump (e.g. no CAP_SYS_ADMIN).
         | 
| 155 | 
            +
                # @example
         | 
| 156 | 
            +
                #   pid1 = Process.spawn('sleep inf')
         | 
| 157 | 
            +
                #   dump_by_pid(pid1, 1)
         | 
| 158 | 
            +
                #   # empty because there is no seccomp installed
         | 
| 159 | 
            +
                #   #=> []
         | 
| 160 | 
            +
                # @example
         | 
| 161 | 
            +
                #   pid2 = Process.spawn('spec/binary/twctf-2016-diary')
         | 
| 162 | 
            +
                #   # give it some time to install the filter
         | 
| 163 | 
            +
                #   sleep(1)
         | 
| 164 | 
            +
                #   dump_by_pid(pid2, 1) { |c| c[0, 10] }
         | 
| 165 | 
            +
                #   #=> [" \x00\x00\x00\x00\x00\x00\x00\x15\x00"]
         | 
| 166 | 
            +
                def dump_by_pid(pid, limit, &block)
         | 
| 167 | 
            +
                  collect = []
         | 
| 168 | 
            +
                  Ptrace.attach_and_wait(pid)
         | 
| 169 | 
            +
                  begin
         | 
| 170 | 
            +
                    i = 0
         | 
| 171 | 
            +
                    while limit.negative? || i < limit
         | 
| 172 | 
            +
                      begin
         | 
| 173 | 
            +
                        bpf = Ptrace.seccomp_get_filter(pid, i)
         | 
| 174 | 
            +
                      rescue Errno::ENOENT, Errno::EINVAL
         | 
| 175 | 
            +
                        break
         | 
| 176 | 
            +
                      end
         | 
| 177 | 
            +
                      collect << (block.nil? ? bpf : yield(bpf, nil))
         | 
| 178 | 
            +
                      i += 1
         | 
| 179 | 
            +
                    end
         | 
| 180 | 
            +
                  ensure
         | 
| 181 | 
            +
                    Ptrace.detach(pid)
         | 
| 182 | 
            +
                  end
         | 
| 183 | 
            +
                  collect
         | 
| 184 | 
            +
                end
         | 
| 132 185 | 
             
              end
         | 
| 133 186 | 
             
            end
         | 
| @@ -42,7 +42,7 @@ module SeccompTools | |
| 42 42 | 
             
                    when :ld then ld(args[0], args[1]) # ld/ldx
         | 
| 43 43 | 
             
                    when :st then st(args[0], args[1]) # st/stx
         | 
| 44 44 | 
             
                    when :jmp then jmp(args[0]) # directly jmp
         | 
| 45 | 
            -
                    when :cmp then cmp(*args[0, 4]) # jmp with  | 
| 45 | 
            +
                    when :cmp then cmp(*args[0, 4]) # jmp with comparison
         | 
| 46 46 | 
             
                    when :alu then alu(args[0], args[1]) # alu
         | 
| 47 47 | 
             
                    when :misc then misc(args[0]) # misc: txa/tax
         | 
| 48 48 | 
             
                    end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'logger'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'seccomp-tools/util'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module SeccompTools
         | 
| 8 | 
            +
              # A logger for internal use.
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # @private
         | 
| 11 | 
            +
              module Logger
         | 
| 12 | 
            +
                module_function
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # Returns a +::Logger+ object for internal logging.
         | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # @return [::Logger]
         | 
| 17 | 
            +
                def logger
         | 
| 18 | 
            +
                  ::Logger.new($stdout).tap do |log|
         | 
| 19 | 
            +
                    log.formatter = proc do |severity, _datetime, _progname, msg|
         | 
| 20 | 
            +
                      prep = ' ' * (severity.size + 3)
         | 
| 21 | 
            +
                      message = msg.lines.map.with_index do |str, i|
         | 
| 22 | 
            +
                        next str if i.zero?
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                        str.strip.empty? ? str : prep + str
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                      color = severity.downcase.to_sym
         | 
| 27 | 
            +
                      msg = +"[#{SeccompTools::Util.colorize(severity, t: color)}] #{message.join}"
         | 
| 28 | 
            +
                      msg << "\n" unless msg.end_with?("\n")
         | 
| 29 | 
            +
                      msg
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                %i[error].each do |sym|
         | 
| 35 | 
            +
                  define_method(sym) do |msg|
         | 
| 36 | 
            +
                    logger.__send__(sym, msg)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
    
        data/lib/seccomp-tools/util.rb
    CHANGED
    
    | @@ -42,13 +42,16 @@ module SeccompTools | |
| 42 42 | 
             
                  !@disable_color && $stdout.tty?
         | 
| 43 43 | 
             
                end
         | 
| 44 44 |  | 
| 45 | 
            +
                # color code of light yellow
         | 
| 46 | 
            +
                LIGHT_YELLOW = "\e[38;5;230m"
         | 
| 45 47 | 
             
                # Color codes for pretty print.
         | 
| 46 48 | 
             
                COLOR_CODE = {
         | 
| 47 49 | 
             
                  esc_m: "\e[0m",
         | 
| 48 50 | 
             
                  syscall: "\e[38;5;120m", # light green
         | 
| 49 | 
            -
                  arch:  | 
| 50 | 
            -
                  args:  | 
| 51 | 
            -
                  gray: "\e[2m"
         | 
| 51 | 
            +
                  arch: LIGHT_YELLOW,
         | 
| 52 | 
            +
                  args: LIGHT_YELLOW,
         | 
| 53 | 
            +
                  gray: "\e[2m",
         | 
| 54 | 
            +
                  error: "\e[38;5;196m" # heavy red
         | 
| 52 55 | 
             
                }.freeze
         | 
| 53 56 | 
             
                # Wrapper color codes.
         | 
| 54 57 | 
             
                # @param [String] s
         | 
    
        metadata
    CHANGED
    
    | @@ -1,43 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: seccomp-tools
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - david942j
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2020-02-16 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            -
              name: pry
         | 
| 15 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            -
                requirements:
         | 
| 17 | 
            -
                - - "~>"
         | 
| 18 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: '0.10'
         | 
| 20 | 
            -
              type: :development
         | 
| 21 | 
            -
              prerelease: false
         | 
| 22 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            -
                requirements:
         | 
| 24 | 
            -
                - - "~>"
         | 
| 25 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: '0.10'
         | 
| 27 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 14 | 
             
              name: rake
         | 
| 29 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 16 | 
             
                requirements:
         | 
| 31 17 | 
             
                - - "~>"
         | 
| 32 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: ' | 
| 19 | 
            +
                    version: '13.0'
         | 
| 34 20 | 
             
              type: :development
         | 
| 35 21 | 
             
              prerelease: false
         | 
| 36 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 23 | 
             
                requirements:
         | 
| 38 24 | 
             
                - - "~>"
         | 
| 39 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: ' | 
| 26 | 
            +
                    version: '13.0'
         | 
| 41 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 28 | 
             
              name: rake-compiler
         | 
| 43 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -58,42 +44,42 @@ dependencies: | |
| 58 44 | 
             
                requirements:
         | 
| 59 45 | 
             
                - - "~>"
         | 
| 60 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: '3. | 
| 47 | 
            +
                    version: '3.9'
         | 
| 62 48 | 
             
              type: :development
         | 
| 63 49 | 
             
              prerelease: false
         | 
| 64 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 51 | 
             
                requirements:
         | 
| 66 52 | 
             
                - - "~>"
         | 
| 67 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: '3. | 
| 54 | 
            +
                    version: '3.9'
         | 
| 69 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 56 | 
             
              name: rubocop
         | 
| 71 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 58 | 
             
                requirements:
         | 
| 73 59 | 
             
                - - "~>"
         | 
| 74 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: '0. | 
| 61 | 
            +
                    version: '0.79'
         | 
| 76 62 | 
             
              type: :development
         | 
| 77 63 | 
             
              prerelease: false
         | 
| 78 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 65 | 
             
                requirements:
         | 
| 80 66 | 
             
                - - "~>"
         | 
| 81 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version: '0. | 
| 68 | 
            +
                    version: '0.79'
         | 
| 83 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 70 | 
             
              name: simplecov
         | 
| 85 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 72 | 
             
                requirements:
         | 
| 87 73 | 
             
                - - "~>"
         | 
| 88 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: 0. | 
| 75 | 
            +
                    version: 0.17.0
         | 
| 90 76 | 
             
              type: :development
         | 
| 91 77 | 
             
              prerelease: false
         | 
| 92 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 79 | 
             
                requirements:
         | 
| 94 80 | 
             
                - - "~>"
         | 
| 95 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version: 0. | 
| 82 | 
            +
                    version: 0.17.0
         | 
| 97 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 84 | 
             
              name: yard
         | 
| 99 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -152,6 +138,7 @@ files: | |
| 152 138 | 
             
            - lib/seccomp-tools/instruction/ret.rb
         | 
| 153 139 | 
             
            - lib/seccomp-tools/instruction/st.rb
         | 
| 154 140 | 
             
            - lib/seccomp-tools/instruction/stx.rb
         | 
| 141 | 
            +
            - lib/seccomp-tools/logger.rb
         | 
| 155 142 | 
             
            - lib/seccomp-tools/syscall.rb
         | 
| 156 143 | 
             
            - lib/seccomp-tools/templates/asm.amd64.asm
         | 
| 157 144 | 
             
            - lib/seccomp-tools/templates/asm.c
         | 
| @@ -174,14 +161,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 174 161 | 
             
              requirements:
         | 
| 175 162 | 
             
              - - ">="
         | 
| 176 163 | 
             
                - !ruby/object:Gem::Version
         | 
| 177 | 
            -
                  version: '2. | 
| 164 | 
            +
                  version: '2.4'
         | 
| 178 165 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 179 166 | 
             
              requirements:
         | 
| 180 167 | 
             
              - - ">="
         | 
| 181 168 | 
             
                - !ruby/object:Gem::Version
         | 
| 182 169 | 
             
                  version: '0'
         | 
| 183 170 | 
             
            requirements: []
         | 
| 184 | 
            -
            rubygems_version: 3.0. | 
| 171 | 
            +
            rubygems_version: 3.0.3
         | 
| 185 172 | 
             
            signing_key: 
         | 
| 186 173 | 
             
            specification_version: 4
         | 
| 187 174 | 
             
            summary: seccomp-tools
         |