On a SELinux disabled system the python call `selinux.security_policyvers()` will fail. Move the logic to find a binary policy from the python script `sepolgen-ifgen` to the C-helper `sepolgen-ifgen-attr-helper`. Change the helper command line interface to accept an optional policy path as second argument. If not given try the current loaded policy (`selinux_current_policy_path`) and if running on a SELinux disabled system iterate over the default store path appending policy versions starting at the maximum supported policy version (`sepol_policy_kern_vers_max`). This changes the helper command line interface from: sepolgen-ifgen-attr-helper policy_file out_file to sepolgen-ifgen-attr-helper out_file [policy_file] and adds a linkage to libselinux. Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- v5: - Do not check bare selinux_binary_policy_path() - Link helper dynamically with libselinux v4: Improve the behavior on no explicit policy path given: - Reorder helper's command line interface - Use loaded policy on SELinux enabled systems v3: Move the iteration logic from sepolgen-ifgen to sepolgen-ifgen-attr-helper and use sepol_policy_kern_vers_max() instead of selinux.security_policyvers(), to work on SELinux disabled systems python/audit2allow/Makefile | 2 +- python/audit2allow/sepolgen-ifgen | 28 ++------------ .../audit2allow/sepolgen-ifgen-attr-helper.c | 38 +++++++++++++++++-- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/python/audit2allow/Makefile b/python/audit2allow/Makefile index 15db5490..025c282a 100644 --- a/python/audit2allow/Makefile +++ b/python/audit2allow/Makefile @@ -18,7 +18,7 @@ endif all: audit2why sepolgen-ifgen-attr-helper -sepolgen-ifgen-attr-helper: sepolgen-ifgen-attr-helper.o $(LIBSEPOLA) +sepolgen-ifgen-attr-helper: sepolgen-ifgen-attr-helper.o $(LIBSEPOLA) -lselinux $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) audit2why: diff --git a/python/audit2allow/sepolgen-ifgen b/python/audit2allow/sepolgen-ifgen index 4a71cda4..b7a04c71 100644 --- a/python/audit2allow/sepolgen-ifgen +++ b/python/audit2allow/sepolgen-ifgen @@ -27,7 +27,6 @@ import sys -import os import tempfile import subprocess @@ -65,37 +64,18 @@ def parse_options(): return options -def get_policy(): - p = selinux.selinux_current_policy_path() - if p and os.path.exists(p): - return p - i = selinux.security_policyvers() - p = selinux.selinux_binary_policy_path() + "." + str(i) - while i > 0 and not os.path.exists(p): - i = i - 1 - p = selinux.selinux_binary_policy_path() + "." + str(i) - if i > 0: - return p - return None - - def get_attrs(policy_path, attr_helper): try: - if not policy_path: - policy_path = get_policy() - if not policy_path: - sys.stderr.write("No installed policy to check\n") - return None outfile = tempfile.NamedTemporaryFile() except IOError as e: sys.stderr.write("could not open attribute output file\n") return None - except OSError: - # SELinux Disabled Machine - return None fd = open("/dev/null", "w") - ret = subprocess.Popen([attr_helper, policy_path, outfile.name], stdout=fd).wait() + if policy_path: + ret = subprocess.Popen([attr_helper, outfile.name, policy_path], stdout=fd).wait() + else: + ret = subprocess.Popen([attr_helper, outfile.name], stdout=fd).wait() fd.close() if ret != 0: sys.stderr.write("could not run attribute helper\n") diff --git a/python/audit2allow/sepolgen-ifgen-attr-helper.c b/python/audit2allow/sepolgen-ifgen-attr-helper.c index 1ce37b0d..53f20818 100644 --- a/python/audit2allow/sepolgen-ifgen-attr-helper.c +++ b/python/audit2allow/sepolgen-ifgen-attr-helper.c @@ -26,6 +26,8 @@ #include <sepol/policydb/avtab.h> #include <sepol/policydb/util.h> +#include <selinux/selinux.h> + #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -147,8 +149,36 @@ static policydb_t *load_policy(const char *filename) policydb_t *policydb; struct policy_file pf; FILE *fp; + char pathname[PATH_MAX]; + int suffix_ver; int ret; + /* no explicit policy name given, try loaded policy on a SELinux enabled system */ + if (!filename) { + filename = selinux_current_policy_path(); + } + + /* + * Fallback to default store paths with version suffixes, + * starting from the maximum supported policy version. + */ + if (!filename) { + for (suffix_ver = sepol_policy_kern_vers_max(); suffix_ver > 0; suffix_ver--) { + snprintf(pathname, sizeof(pathname), "%s.%d", selinux_binary_policy_path(), suffix_ver); + + if (access(pathname, F_OK) == 0) { + filename = pathname; + break; + } + } + + if (!filename) { + fprintf(stderr, "Can't find any policy at '%s'\n", + selinux_binary_policy_path()); + return NULL; + } + } + fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "Can't open '%s': %s\n", @@ -188,7 +218,7 @@ static policydb_t *load_policy(const char *filename) void usage(char *progname) { - printf("usage: %s policy_file out_file\n", progname); + printf("usage: %s out_file [policy_file]\n", progname); } int main(int argc, char **argv) @@ -197,18 +227,18 @@ int main(int argc, char **argv) struct callback_data cb_data; FILE *fp; - if (argc != 3) { + if (argc != 2 && argc != 3) { usage(argv[0]); return -1; } /* Open the policy. */ - p = load_policy(argv[1]); + p = load_policy(argv[2]); if (p == NULL) return -1; /* Open the output policy. */ - fp = fopen(argv[2], "w"); + fp = fopen(argv[1], "w"); if (fp == NULL) { fprintf(stderr, "error opening output file\n"); policydb_destroy(p); -- 2.27.0