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