lin
2025-08-14 dae8bad597b6607a449b32bf76c523423f7720ed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Helper tool to compile a BPF program from a Minijail seccomp filter.
 
This script will take a Minijail seccomp policy file and compile it into a
BPF program suitable for use with Minijail in the current architecture.
"""
 
from __future__ import print_function
 
import argparse
import sys
 
import arch
import bpf
import compiler
import parser
 
 
def parse_args(argv):
    """Return the parsed CLI arguments for this tool."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '--optimization-strategy',
        default=compiler.OptimizationStrategy.BST,
        type=compiler.OptimizationStrategy,
        choices=list(compiler.OptimizationStrategy))
    parser.add_argument('--include-depth-limit', default=10)
    parser.add_argument('--arch-json', default='constants.json')
    parser.add_argument(
        '--default-action',
        type=str,
        help=('Use the specified default action, overriding any @default '
              'action found in the .policy files. '
              'This allows the use of permissive actions (allow, log, trace) '
              'since it is not valid to specify a permissive action in '
              '.policy files. This is useful for debugging.'))
    parser.add_argument(
        '--use-kill-process',
        action='store_true',
        help=('Use SECCOMP_RET_KILL_PROCESS instead of '
              'SECCOMP_RET_KILL_THREAD (requires Linux v4.14+).'))
    parser.add_argument(
        'policy', help='The seccomp policy.', type=argparse.FileType('r'))
    parser.add_argument(
        'output', help='The BPF program.', type=argparse.FileType('wb'))
    return parser.parse_args(argv)
 
 
def main(argv):
    """Main entrypoint."""
    opts = parse_args(argv)
    parsed_arch = arch.Arch.load_from_json(opts.arch_json)
    policy_compiler = compiler.PolicyCompiler(parsed_arch)
    if opts.use_kill_process:
        kill_action = bpf.KillProcess()
    else:
        kill_action = bpf.KillThread()
    override_default_action = None
    if opts.default_action:
        parser_state = parser.ParserState('<memory>')
        parser_state.set_line(opts.default_action)
        override_default_action = parser.PolicyParser(
            parsed_arch, kill_action=bpf.KillProcess()).parse_action(
                parser_state.tokenize())
    with opts.output as outf:
        outf.write(
            policy_compiler.compile_file(
                opts.policy.name,
                optimization_strategy=opts.optimization_strategy,
                kill_action=kill_action,
                include_depth_limit=opts.include_depth_limit,
                override_default_action=override_default_action).opcodes)
    return 0
 
 
if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))