111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepfrom optparse import OptionParser
211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepfrom optparse import Option, OptionValueError
311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepimport os
411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepimport policy
511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepimport re
611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepimport sys
711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep#############################################################
911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep# Tests
1011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep#############################################################
1111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepdef TestDataTypeViolations(pol):
1211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    return pol.AssertPathTypesHaveAttr(["/data/"], [], "data_file_type")
1311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
1411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepdef TestSysfsTypeViolations(pol):
1511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    return pol.AssertPathTypesHaveAttr(["/sys/"], ["/sys/kernel/debug/",
1611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep                                    "/sys/kernel/tracing"], "sysfs_type")
1711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
1811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepdef TestDebugfsTypeViolations(pol):
1911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    # TODO: this should apply to genfs_context entries as well
2011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    return pol.AssertPathTypesHaveAttr(["/sys/kernel/debug/",
2111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep                                    "/sys/kernel/tracing"], [], "debugfs_type")
2211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep###
2311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep# extend OptionParser to allow the same option flag to be used multiple times.
2411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep# This is used to allow multiple file_contexts files and tests to be
2511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep# specified.
2611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep#
2711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepclass MultipleOption(Option):
2811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    ACTIONS = Option.ACTIONS + ("extend",)
2911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
3011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
3111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
3211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
3311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    def take_action(self, action, dest, opt, value, values, parser):
3411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        if action == "extend":
3511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep            values.ensure_value(dest, []).append(value)
3611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        else:
3711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep            Option.take_action(self, action, dest, opt, value, values, parser)
3811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
3911d096fc998573e22115df921cfd13000146c4d7Jeff Vander StoepTests = ["TestDataTypeViolators"]
4011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
4111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoepif __name__ == '__main__':
4211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    usage = "sepolicy_tests.py -f nonplat_file_contexts -f "
4311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    usage +="plat_file_contexts -p policy [--test test] [--help]"
4411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    parser = OptionParser(option_class=MultipleOption, usage=usage)
4511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    parser.add_option("-f", "--file_contexts", dest="file_contexts",
4611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep            metavar="FILE", action="extend", type="string")
4711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
4811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    parser.add_option("-l", "--library-path", dest="libpath", metavar="FILE")
4911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    parser.add_option("-t", "--test", dest="test", action="extend",
5011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep            help="Test options include "+str(Tests))
5111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
5211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    (options, args) = parser.parse_args()
5311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
5411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if not options.libpath:
5511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit("Must specify path to host libraries\n" + parser.usage)
5611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if not os.path.exists(options.libpath):
5711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit("Error: library-path " + options.libpath + " does not exist\n"
5811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep                + parser.usage)
5911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
6011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if not options.policy:
6111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit("Must specify monolithic policy file\n" + parser.usage)
6211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if not os.path.exists(options.policy):
6311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit("Error: policy file " + options.policy + " does not exist\n"
6411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep                + parser.usage)
6511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
6611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if not options.file_contexts:
6711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit("Error: Must specify file_contexts file(s)\n" + parser.usage)
6811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    for f in options.file_contexts:
6911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        if not os.path.exists(f):
7011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep            sys.exit("Error: File_contexts file " + f + " does not exist\n" +
7111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep                    parser.usage)
7211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
7311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    pol = policy.Policy(options.policy, options.file_contexts, options.libpath)
7411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
7511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    results = ""
7611d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    # If an individual test is not specified, run all tests.
7711d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if options.test is None or "TestDataTypeViolations" in options.tests:
7811d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        results += TestDataTypeViolations(pol)
7911d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if options.test is None or "TestSysfsTypeViolations" in options.tests:
8011d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        results += TestSysfsTypeViolations(pol)
8111d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if options.test is None or "TestDebugfsTypeViolations" in options.tests:
8211d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        results += TestDebugfsTypeViolations(pol)
8311d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep
8411d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep    if len(results) > 0:
8511d096fc998573e22115df921cfd13000146c4d7Jeff Vander Stoep        sys.exit(results)
86