xref: /aosp_15_r20/external/selinux/python/audit2allow/sepolgen-ifgen (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1#!/usr/bin/python3 -EsI
2#
3# Authors: Karl MacMillan <[email protected]>
4#
5# Copyright (C) 2006 Red Hat
6# see file 'COPYING' for use and warranty information
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2 only
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20#
21
22# Parse interfaces and output extracted information about them
23# suitable for policy generation. By default writes the output
24# to the default location (obtained from sepolgen.defaults), but
25# will output to another file provided as an argument:
26#   sepolgen-ifgen [headers] [output-filename]
27
28
29import sys
30import tempfile
31import subprocess
32
33import selinux
34
35import sepolgen.refparser as refparser
36import sepolgen.defaults as defaults
37import sepolgen.interfaces as interfaces
38
39
40VERSION = "%prog .1"
41ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"
42
43
44def parse_options():
45    from optparse import OptionParser
46
47    parser = OptionParser(version=VERSION)
48    parser.add_option("-o", "--output", dest="output", default=defaults.interface_info(),
49                      help="filename to store output")
50    parser.add_option("-i", "--interfaces", dest="headers", default=defaults.headers(),
51                      help="location of the interface header files")
52    parser.add_option("-a", "--attribute_info", dest="attribute_info")
53    parser.add_option("-p", "--policy", dest="policy_path")
54    parser.add_option("-v", "--verbose", action="store_true", default=False,
55                      help="print debugging output")
56    parser.add_option("-d", "--debug", action="store_true", default=False,
57                      help="extra debugging output")
58    parser.add_option("--attr-helper", default=ATTR_HELPER,
59                      help="path to sepolgen-ifgen-attr-helper")
60    parser.add_option("--no_attrs", action="store_true", default=False,
61                      help="do not retrieve attribute access from kernel policy")
62    options, args = parser.parse_args()
63
64    return options
65
66
67def get_attrs(policy_path, attr_helper):
68    try:
69        outfile = tempfile.NamedTemporaryFile()
70    except IOError as e:
71        sys.stderr.write("could not open attribute output file\n")
72        return None
73
74    fd = open("/dev/null", "w")
75    if policy_path:
76        ret = subprocess.Popen([attr_helper, outfile.name, policy_path], stdout=fd).wait()
77    else:
78        ret = subprocess.Popen([attr_helper, outfile.name], stdout=fd).wait()
79    fd.close()
80    if ret != 0:
81        sys.stderr.write("could not run attribute helper\n")
82        return None
83
84    attrs = interfaces.AttributeSet()
85    try:
86        attrs.from_file(outfile)
87    except:
88        print("error parsing attribute info")
89        return None
90
91    return attrs
92
93
94def main():
95    options = parse_options()
96
97    # Open the output first to generate errors before parsing
98    try:
99        f = open(options.output, "w")
100    except IOError as e:
101        sys.stderr.write("could not open output file [%s]\n" % options.output)
102        return 1
103
104    if options.verbose:
105        log = sys.stdout
106    else:
107        log = None
108
109    # Get the attributes from the binary
110    attrs = None
111    if not options.no_attrs:
112        attrs = get_attrs(options.policy_path, options.attr_helper)
113        if attrs is None:
114            return 1
115
116    # Parse the headers
117    try:
118        headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
119    except ValueError as e:
120        sys.stderr.write("error parsing headers: %s\n" % e)
121        return 1
122
123    if_set = interfaces.InterfaceSet(output=log)
124    if_set.add_headers(headers, attributes=attrs)
125    if_set.to_file(f)
126    f.close()
127
128    if refparser.success:
129        return 0
130    else:
131        return 1
132
133if __name__ == "__main__":
134    sys.exit(main())
135