Path: blob/main/tests/integration_tests/security/test_custom_seccomp.py
1958 views
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.1# SPDX-License-Identifier: Apache-2.02"""Tests that the --seccomp-filter parameter works as expected."""34import os5import platform6import json7import tempfile8import time9import psutil10import pytest11import requests12import framework.utils as utils13import host_tools.logging as log_tools1415from host_tools.cargo_build import run_seccompiler_bin161718def _custom_filter_setup(test_microvm, json_filter):19json_temp = tempfile.NamedTemporaryFile(delete=False)20json_temp.write(json_filter)21json_temp.flush()2223bpf_path = os.path.join(test_microvm.path, 'bpf.out')2425run_seccompiler_bin(bpf_path=bpf_path, json_path=json_temp.name)2627os.unlink(json_temp.name)28test_microvm.create_jailed_resource(bpf_path)29test_microvm.jailer.extra_args.update({"seccomp-filter": 'bpf.out'})303132def _config_file_setup(test_microvm, vm_config_file):33test_microvm.create_jailed_resource(test_microvm.kernel_file,34create_jail=True)35test_microvm.create_jailed_resource(test_microvm.rootfs_file,36create_jail=True)3738vm_config_path = os.path.join(test_microvm.path,39os.path.basename(vm_config_file))40with open(vm_config_file) as f1:41with open(vm_config_path, "w") as f2:42for line in f1:43f2.write(line)44test_microvm.create_jailed_resource(vm_config_path, create_jail=True)45test_microvm.jailer.extra_args = {'config-file': os.path.basename(46vm_config_file)}4748test_microvm.jailer.extra_args.update({'no-api': None})495051def test_allow_all(test_microvm_with_api):52"""Test --seccomp-filter, allowing all syscalls."""53test_microvm = test_microvm_with_api5455_custom_filter_setup(test_microvm, """{56"Vmm": {57"default_action": "allow",58"filter_action": "trap",59"filter": []60},61"Api": {62"default_action": "allow",63"filter_action": "trap",64"filter": []65},66"Vcpu": {67"default_action": "allow",68"filter_action": "trap",69"filter": []70}71}""".encode('utf-8'))7273test_microvm.spawn()7475test_microvm.basic_config()7677test_microvm.start()7879utils.assert_seccomp_level(test_microvm.jailer_clone_pid, "2")808182def test_working_filter(test_microvm_with_api):83"""Test --seccomp-filter, rejecting some dangerous syscalls."""84test_microvm = test_microvm_with_api8586_custom_filter_setup(test_microvm, """{87"Vmm": {88"default_action": "allow",89"filter_action": "kill_process",90"filter": [91{92"syscall": "clone"93},94{95"syscall": "execve"96}97]98},99"Api": {100"default_action": "allow",101"filter_action": "kill_process",102"filter": [103{104"syscall": "clone"105},106{107"syscall": "execve"108}109]110},111"Vcpu": {112"default_action": "allow",113"filter_action": "kill_process",114"filter": [115{116"syscall": "clone"117},118{119"syscall": "execve",120"comment": "sample comment"121}122]123}124}""".encode("utf-8"))125126test_microvm.spawn()127128test_microvm.basic_config()129130test_microvm.start()131132# seccomp-level should be 2, with no additional errors133utils.assert_seccomp_level(test_microvm.jailer_clone_pid, "2")134135136def test_failing_filter(test_microvm_with_api):137"""Test --seccomp-filter, denying some needed syscalls."""138test_microvm = test_microvm_with_api139140_custom_filter_setup(test_microvm, """{141"Vmm": {142"default_action": "allow",143"filter_action": "trap",144"filter": []145},146"Api": {147"default_action": "allow",148"filter_action": "trap",149"filter": []150},151"Vcpu": {152"default_action": "allow",153"filter_action": "trap",154"filter": [155{156"syscall": "ioctl"157}158]159}160}""".encode('utf-8'))161162test_microvm.spawn()163164test_microvm.basic_config(vcpu_count=1)165166metrics_fifo_path = os.path.join(test_microvm.path, 'metrics_fifo')167metrics_fifo = log_tools.Fifo(metrics_fifo_path)168response = test_microvm.metrics.put(169metrics_path=test_microvm.create_jailed_resource(metrics_fifo.path)170)171assert test_microvm.api_session.is_status_no_content(response.status_code)172173# Try to start the VM with error checking off, because it will fail.174try:175test_microvm.start(check=False)176except requests.exceptions.ConnectionError:177pass178179# Give time for the process to get killed180time.sleep(1)181182test_microvm.expect_kill_by_signal = True183# Check the logger output184ioctl_num = 16 if platform.machine() == "x86_64" else 29185assert "Shutting down VM after intercepting a bad syscall ({})".format(186str(ioctl_num)) in test_microvm.log_data187188# Check the metrics189lines = metrics_fifo.sequential_reader(100)190191num_faults = 0192for line in lines:193num_faults += json.loads(line)["seccomp"]["num_faults"]194195assert num_faults == 1196197# assert that the process was killed198assert not psutil.pid_exists(test_microvm.jailer_clone_pid)199200201@pytest.mark.parametrize(202"vm_config_file",203["framework/vm_config.json"]204)205def test_invalid_bpf(test_microvm_with_ssh, vm_config_file):206"""Test that FC does not start, given an invalid binary filter."""207test_microvm = test_microvm_with_ssh208209# Configure VM from JSON. Otherwise, the test will error because210# the process will be killed before configuring the API socket.211_config_file_setup(test_microvm_with_ssh, vm_config_file)212213bpf_path = os.path.join(test_microvm.path, 'bpf.out')214file = open(bpf_path, "w")215file.write("Invalid BPF!")216file.close()217218test_microvm.create_jailed_resource(bpf_path)219test_microvm.jailer.extra_args.update({"seccomp-filter": 'bpf.out'})220221test_microvm.spawn()222223# give time for the process to get killed224time.sleep(1)225226# assert that the process was killed227assert not psutil.pid_exists(test_microvm.jailer_clone_pid)228229230