/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "analyze-syscall-filter.h"
#include "analyze.h"
#include "fd-util.h"
#include "fileio.h"
#include "nulstr-util.h"
#include "seccomp-util.h"
#include "set.h"
#include "strv.h"
#include "terminal-util.h"

#if HAVE_SECCOMP

static int load_kernel_syscalls(Set **ret) {
        _cleanup_set_free_ Set *syscalls = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        /* Let's read the available system calls from the list of available tracing events. Slightly dirty,
         * but good enough for analysis purposes. */

        f = fopen("/sys/kernel/tracing/available_events", "re");
        if (!f) {
                /* We tried the non-debugfs mount point and that didn't work. If it wasn't mounted, maybe the
                 * old debugfs mount point works? */
                f = fopen("/sys/kernel/debug/tracing/available_events", "re");
                if (!f)
                        return log_full_errno(IN_SET(errno, EPERM, EACCES, ENOENT) ? LOG_DEBUG : LOG_WARNING, errno,
                                              "Can't read open tracefs' available_events file: %m");
        }

        for (;;) {
                _cleanup_free_ char *line = NULL;
                const char *e;

                r = read_line(f, LONG_LINE_MAX, &line);
                if (r < 0)
                        return log_error_errno(r, "Failed to read system call list: %m");
                if (r == 0)
                        break;

                e = startswith(line, "syscalls:sys_enter_");
                if (!e)
                        continue;

                /* These are named differently inside the kernel than their external name for historical
                 * reasons. Let's hide them here. */
                if (STR_IN_SET(e, "newuname", "newfstat", "newstat", "newlstat", "sysctl"))
                        continue;

                r = set_put_strdup(&syscalls, e);
                if (r < 0)
                        return log_error_errno(r, "Failed to add system call to list: %m");
        }

        *ret = TAKE_PTR(syscalls);
        return 0;
}

static int syscall_set_add(Set **s, const SyscallFilterSet *set) {
        int r;

        assert(s);

        if (!set)
                return 0;

        NULSTR_FOREACH(sc, set->value) {
                if (sc[0] == '@')
                        continue;

                r = set_put_strdup(s, sc);
                if (r < 0)
                        return r;
        }

        return 0;
}

static void syscall_set_remove(Set *s, const SyscallFilterSet *set) {
        if (!set)
                return;

        NULSTR_FOREACH(sc, set->value) {
                if (sc[0] == '@')
                        continue;

                free(set_remove(s, sc));
        }
}

static void dump_syscall_filter(const SyscallFilterSet *set) {
        printf("%s%s%s\n"
               "    # %s\n",
               ansi_highlight(),
               set->name,
               ansi_normal(),
               set->help);

        NULSTR_FOREACH(syscall, set->value)
                printf("    %s%s%s\n", syscall[0] == '@' ? ansi_underline() : "", syscall, ansi_normal());
}

int verb_syscall_filters(int argc, char *argv[], void *userdata) {
        bool first = true;
        int r;

        pager_open(arg_pager_flags);

        if (strv_isempty(strv_skip(argv, 1))) {
                _cleanup_set_free_ Set *kernel = NULL, *known = NULL;
                int k = 0;  /* explicit initialization to appease gcc */

                r = syscall_set_add(&known, syscall_filter_sets + SYSCALL_FILTER_SET_KNOWN);
                if (r < 0)
                        return log_error_errno(r, "Failed to prepare set of known system calls: %m");

                if (!arg_quiet)
                        k = load_kernel_syscalls(&kernel);

                for (int i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
                        const SyscallFilterSet *set = syscall_filter_sets + i;
                        if (!first)
                                puts("");

                        dump_syscall_filter(set);
                        syscall_set_remove(kernel, set);
                        if (i != SYSCALL_FILTER_SET_KNOWN)
                                syscall_set_remove(known, set);
                        first = false;
                }

                if (arg_quiet)  /* Let's not show the extra stuff in quiet mode */
                        return 0;

                if (!set_isempty(known)) {
                        _cleanup_free_ char **l = NULL;

                        printf("\n"
                               "# %sUngrouped System Calls%s (known but not included in any of the groups except @known):\n",
                               ansi_highlight(), ansi_normal());

                        l = set_get_strv(known);
                        if (!l)
                                return log_oom();

                        strv_sort(l);

                        STRV_FOREACH(syscall, l)
                                printf("#   %s\n", *syscall);
                }

                if (k < 0) {
                        fputc('\n', stdout);
                        fflush(stdout);
                        if (!arg_quiet)
                                log_notice_errno(k, "# Not showing unlisted system calls, couldn't retrieve kernel system call list: %m");
                } else if (!set_isempty(kernel)) {
                        _cleanup_free_ char **l = NULL;

                        printf("\n"
                               "# %sUnlisted System Calls%s (supported by the local kernel, but not included in any of the groups listed above):\n",
                               ansi_highlight(), ansi_normal());

                        l = set_get_strv(kernel);
                        if (!l)
                                return log_oom();

                        strv_sort(l);

                        STRV_FOREACH(syscall, l)
                                printf("#   %s\n", *syscall);
                }
        } else
                STRV_FOREACH(name, strv_skip(argv, 1)) {
                        const SyscallFilterSet *set;

                        if (!first)
                                puts("");

                        set = syscall_filter_set_find(*name);
                        if (!set) {
                                /* make sure the error appears below normal output */
                                fflush(stdout);

                                return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
                                                       "Filter set \"%s\" not found.", *name);
                        }

                        dump_syscall_filter(set);
                        first = false;
                }

        return EXIT_SUCCESS;
}

#else
int verb_syscall_filters(int argc, char *argv[], void *userdata) {
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not compiled with syscall filters, sorry.");
}
#endif
