Пример #1
0
def test_merge() -> None:
    sys_arch = pyseccomp.system_arch()
    nonsys_arch = nonsystem_arch()

    filt_a = pyseccomp.SyscallFilter(pyseccomp.KILL)

    assert filt_a.exist_arch(sys_arch)
    assert not filt_a.exist_arch(nonsys_arch)

    filt_b = pyseccomp.SyscallFilter(pyseccomp.KILL)
    filt_b.add_arch(nonsys_arch)
    filt_b.remove_arch(sys_arch)

    assert not filt_b.exist_arch(sys_arch)
    assert filt_b.exist_arch(nonsys_arch)

    filt_a.merge(filt_b)

    # Filter A has both
    assert filt_a.exist_arch(sys_arch)
    assert filt_a.exist_arch(nonsys_arch)

    # Filter B was reset
    assert filt_b.exist_arch(sys_arch)
    assert not filt_b.exist_arch(nonsys_arch)
Пример #2
0
def test_getpriority_pid_1() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    filt.add_rule(pyseccomp.ERRNO(errno.EPERM), "getpriority",
                  pyseccomp.Arg(1, pyseccomp.EQ, 1))

    pid = os.fork()
    if pid == 0:
        try:
            os.getpriority(os.PRIO_PROCESS, 0)
            os.getpriority(os.PRIO_PROCESS, 1)

            filt.load()

            os.getpriority(os.PRIO_PROCESS, 0)

            with pytest.raises(PermissionError):
                os.getpriority(os.PRIO_PROCESS, 1)

        except Exception:  # pylint: disable=broad-except
            traceback.print_exc()
            os._exit(1)  # pylint: disable=protected-access
        finally:
            os._exit(0)  # pylint: disable=protected-access

    _, wstatus = os.waitpid(pid, 0)
    assert os.WIFEXITED(wstatus)
    assert os.WEXITSTATUS(wstatus) == 0
Пример #3
0
def test_nice_eperm_exactly() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    for name in ["nice", "setpriority"]:
        sys_nr = pyseccomp.resolve_syscall(pyseccomp.Arch.NATIVE, name)
        if sys_nr >= 0:
            filt.add_rule_exactly(pyseccomp.ERRNO(errno.EPERM), sys_nr)

    pid = os.fork()
    if pid == 0:
        try:
            os.nice(0)

            filt.load()

            with pytest.raises(PermissionError):
                os.nice(0)

        except Exception:  # pylint: disable=broad-except
            traceback.print_exc()
            os._exit(1)  # pylint: disable=protected-access
        finally:
            os._exit(0)  # pylint: disable=protected-access

    _, wstatus = os.waitpid(pid, 0)
    assert os.WIFEXITED(wstatus)
    assert os.WEXITSTATUS(wstatus) == 0
Пример #4
0
def test_nice_eperm() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    filt.add_rule(pyseccomp.ERRNO(errno.EPERM), "nice")
    filt.add_rule(pyseccomp.ERRNO(errno.EPERM), "setpriority")

    pid = os.fork()
    if pid == 0:
        try:
            if cov_init is not None:
                cov_init()

            os.nice(0)

            filt.load()

            with pytest.raises(PermissionError):
                os.nice(0)

            if cov_cleanup is not None:
                cov_cleanup()

        except Exception:  # pylint: disable=broad-except
            traceback.print_exc()
            os._exit(1)  # pylint: disable=protected-access
        finally:
            os._exit(0)  # pylint: disable=protected-access

    _, wstatus = os.waitpid(pid, 0)
    assert os.WIFEXITED(wstatus)
    assert os.WEXITSTATUS(wstatus) == 0
Пример #5
0
def test_get_set_attr() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.KILL)

    filt.set_attr(pyseccomp.Attr.CTL_NNP, 1)
    assert filt.get_attr(pyseccomp.Attr.CTL_NNP) == 1

    filt.set_attr(pyseccomp.Attr.CTL_NNP, 0)
    assert filt.get_attr(pyseccomp.Attr.CTL_NNP) == 0
Пример #6
0
def test_export_pfc() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.KILL)

    r_fd, w_fd = os.pipe()
    with open(r_fd, "rb") as rfile:
        with open(w_fd, "wb") as wfile:
            filt.export_pfc(wfile)

        assert rfile.read() != b""
Пример #7
0
def test_remove_arch_native() -> None:
    filt = pyseccomp.SyscallFilter(defaction=pyseccomp.KILL)

    filt.remove_arch(pyseccomp.Arch.NATIVE)

    with pytest.raises(FileExistsError):
        filt.remove_arch(pyseccomp.system_arch())

    with pytest.raises(FileExistsError):
        filt.remove_arch(nonsystem_arch())
Пример #8
0
def test_bad_arch() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    with pytest.raises(OSError, match="Invalid argument"):
        filt.add_arch(0xDEADBEEF)

    with pytest.raises(OSError, match="Invalid argument"):
        filt.remove_arch(0xDEADBEEF)

    with pytest.raises(OSError, match="Invalid argument"):
        filt.exist_arch(0xDEADBEEF)
Пример #9
0
def test_reset() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.KILL)

    nonsys_arch = nonsystem_arch()
    filt.add_arch(nonsys_arch)
    assert filt.exist_arch(nonsys_arch)

    filt.reset(pyseccomp.KILL)

    # The arch should now be absent
    assert not filt.exist_arch(nonsys_arch)
Пример #10
0
def test_syscall_priority() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.KILL)

    filt.syscall_priority(
        pyseccomp.resolve_syscall(pyseccomp.Arch.NATIVE, "write"), 100)
    filt.syscall_priority("write", 100)

    for syscall in [
            pyseccomp.resolve_syscall(pyseccomp.Arch.NATIVE, "NOEXIST"),
            "NOEXIST"
    ]:
        with pytest.raises(OSError, match=r"Invalid argument"):
            filt.syscall_priority(cast(Union[int, str], syscall), 100)
Пример #11
0
def test_notification_resp_success() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)
    filt.add_rule(pyseccomp.NOTIFY, "setpriority")

    pid = os.fork()
    if pid == 0:
        try:
            if cov_init is not None:
                cov_init()

            filt.load()

            pid = os.fork()
            if pid == 0:
                try:
                    os.setpriority(os.PRIO_PROCESS, 0, os.getpriority(os.PRIO_PROCESS, 0))
                except BaseException:  # pylint: disable=broad-except
                    traceback.print_exc()
                    os._exit(1)  # pylint: disable=protected-access
                finally:
                    os._exit(0)  # pylint: disable=protected-access

            notif = filt.receive_notify()

            assert notif.syscall == pyseccomp.resolve_syscall(pyseccomp.Arch.NATIVE, "setpriority")
            assert notif.syscall_arch == pyseccomp.system_arch()
            assert notif.syscall_args[:3] == [
                os.PRIO_PROCESS,
                0,
                os.getpriority(os.PRIO_PROCESS, 0),
            ]

            filt.respond_notify(pyseccomp.NotificationResponse(0, 0, notif.id, 1))

            _, wstatus = os.waitpid(pid, 0)
            assert os.WIFEXITED(wstatus)
            assert os.WEXITSTATUS(wstatus) == 0

            if cov_cleanup is not None:
                cov_cleanup()

        except BaseException:  # pylint: disable=broad-except
            traceback.print_exc()
            os._exit(1)  # pylint: disable=protected-access
        finally:
            os._exit(0)  # pylint: disable=protected-access

    _, wstatus = os.waitpid(pid, 0)
    assert os.WIFEXITED(wstatus)
    assert os.WEXITSTATUS(wstatus) == 0
Пример #12
0
def test_bad_rule_args() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    with pytest.raises(ValueError, match=r"^Too many arguments$"):
        filt.add_rule(
            pyseccomp.KILL_PROCESS,
            "prctl",
            pyseccomp.Arg(1, pyseccomp.EQ, 0),
            pyseccomp.Arg(2, pyseccomp.EQ, 0),
            pyseccomp.Arg(3, pyseccomp.EQ, 0),
            pyseccomp.Arg(4, pyseccomp.EQ, 0),
            pyseccomp.Arg(5, pyseccomp.EQ, 0),
            pyseccomp.Arg(6, pyseccomp.EQ, 0),
            pyseccomp.Arg(7, pyseccomp.EQ, 0),
        )
Пример #13
0
def test_nice_kill_exactly() -> None:
    filt = pyseccomp.SyscallFilter(pyseccomp.ALLOW)

    for name in ["nice", "setpriority"]:
        sys_nr = pyseccomp.resolve_syscall(pyseccomp.Arch.NATIVE, name)
        if sys_nr >= 0:
            filt.add_rule_exactly(pyseccomp.KILL, name)

    pid = os.fork()
    if pid == 0:
        try:
            os.nice(0)

            filt.load()

            os.nice(0)
        finally:
            os._exit(0)  # pylint: disable=protected-access

    _, wstatus = os.waitpid(pid, 0)
    assert os.WIFSIGNALED(wstatus)
    assert os.WTERMSIG(wstatus) == signal.SIGSYS
Пример #14
0
def test_bad_action() -> None:
    with pytest.raises(OSError, match="Invalid argument"):
        pyseccomp.SyscallFilter(0xDEADBEEF)
Пример #15
0
def test_has_arch() -> None:
    filt = pyseccomp.SyscallFilter(defaction=pyseccomp.KILL)

    assert filt.exist_arch(pyseccomp.Arch.NATIVE)
    assert filt.exist_arch(pyseccomp.system_arch())
    assert not filt.exist_arch(nonsystem_arch())