def test_fuzz_trace_file():
    fuzzing_time_seconds = 10 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Make sure AFL is installed
    if not is_afl_installed():
        install_afl()

    # Create trace files
    iotrace.start_tracing()
    iotrace.stop_tracing()
    trace_repo_path = iotrace.parse_json(
        iotrace.get_trace_repository_path())[0]['path']
    trace_path = trace_repo_path + "/" + iotrace.get_latest_trace_path()
    tracefile_path = f'{trace_path}/octf.trace.0'
    copied_tracefile_path = f'{repo_path}/rootfs/var/lib/octf/trace/' + \
                            f'{iotrace.get_latest_trace_path()}/octf.trace.0'

    # Create patch file for redirecting fuzzed stdin to trace file
    new_patch_path: str = f'{iotrace.working_dir}/redirect_to_tracefile.patch'
    create_patch_redirect_fuzz_to_file(f'{copied_tracefile_path}',
                                       new_patch_path)

    # Install iotrace locally with AFL support and redirect patch
    install_iotrace_with_afl_support(new_patch_path)

    # Copy trace files to local instalation of iotrace
    TestRun.executor.run_expect_success(
        f'cp -r {trace_repo_path}/kernel '
        f'{repo_path}/rootfs/var/lib/octf/trace/')

    # Instruct the system to output coredumps as files instead of sending them
    # to a specific crash handler app
    TestRun.LOGGER.info('Setting up system for fuzzing')
    TestRun.executor.run_expect_success(
        'echo core > /proc/sys/kernel/core_pattern')
    TestRun.executor.run_expect_success(
        f'cd {repo_path} && mkdir -p afl-i afl-o')

    # Add input seed which shall be mutated
    TestRun.executor.run_expect_success(
        f'cd {repo_path} && echo "0" > afl-i/case0')

    TestRun.LOGGER.info(
        f'Starting fuzzing {tracefile_path} This should take ' +
        str(fuzzing_time_seconds / 60) + ' minutes')
    TestRun.executor.run(f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
                         '"rootfs/bin/iotrace --get-trace-statistics -p '
                         f'{iotrace.get_latest_trace_path()}" --one-job')
    output = wait_for_completion(fuzzing_time_seconds, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    detect_crashes(output.stdout)
def test_fuzz_config():
    fuzzing_time_seconds = 10 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Make sure AFL is installed
    if not is_afl_installed():
        install_afl()

    # Create patch file for redirecting fuzzed stdin to config file path
    new_patch_path: str = f'{iotrace.working_dir}/redirect_to_config.patch'
    create_patch_redirect_fuzz_to_file(
        f'{repo_path}/rootfs/etc/octf/octf.conf', new_patch_path)

    # Install iotrace locally with AFL support and redirect patch
    install_iotrace_with_afl_support(new_patch_path)

    # Instruct the system to output coredumps as files instead of sending them
    # to a specific crash handler app
    TestRun.LOGGER.info('Setting up system for fuzzing')
    TestRun.executor.run_expect_success(
        'echo core > /proc/sys/kernel/core_pattern')
    TestRun.executor.run_expect_success(
        f'cd {repo_path} && mkdir -p afl-i afl-o')

    # Use config as seed to be mutated
    TestRun.executor.run_expect_success(
        f'cp {repo_path}/rootfs/etc/octf/octf.conf'
        f' {repo_path}/afl-i/case0')

    TestRun.LOGGER.info('Starting fuzzing octf.conf. This should take ' +
                        str(fuzzing_time_seconds / 60) + ' minutes')

    TestRun.LOGGER.info("Trying 'list-traces' command")
    TestRun.executor.run(f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
                         '"rootfs/bin/iotrace -L" --one-job')
    output = wait_for_completion(fuzzing_time_seconds / 2, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    detect_crashes(output.stdout)

    TestRun.LOGGER.info("Trying 'get-trace-repository-path' command")
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
        '"rootfs/bin/iotrace --get-trace-repository" --one-job')
    output = wait_for_completion(fuzzing_time_seconds / 2, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    detect_crashes(output.stdout)
def test_fuzz_trace_file():
    fuzzing_time_seconds = 20 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Create trace files
    iotrace.start_tracing()
    iotrace.stop_tracing()
    trace_repo_path = IotracePlugin.get_trace_repository_path()
    trace_path = trace_repo_path + "/" + IotracePlugin.get_latest_trace_path()
    tracefile_path = f'{trace_path}/octf.trace.0'
    copied_tracefile_path = f'{repo_path}/rootfs/var/lib/octf/trace/' + \
                            f'{IotracePlugin.get_latest_trace_path()}' \
                            f'/octf.trace.0'

    # Create patch file for redirecting fuzzed stdin to trace file
    new_patch_path: str = f'{iotrace.working_dir}/redirect_to_tracefile.patch'
    create_patch_redirect_fuzz_to_file(f'{copied_tracefile_path}',
                                       new_patch_path)

    # Install iotrace locally with AFL support and redirect patch
    install_iotrace_with_afl_support(new_patch_path, [
        'modules/open-cas-telemetry-framework', 'modules/test-framework',
        'source/kernel'
    ])

    # Copy trace files to local instalation of iotrace
    TestRun.executor.run_expect_success(
        f'cp -r {trace_repo_path}/kernel '
        f'{repo_path}/rootfs/var/lib/octf/trace/')

    TestRun.executor.run_expect_success(
        f'cd {repo_path} && mkdir -p afl-i afl-o')
    # Add input seed which shall be mutated
    TestRun.executor.run_expect_success(
        f'cd {repo_path} && echo "0" > afl-i/case0')

    TestRun.LOGGER.info(
        f'Starting fuzzing {tracefile_path} This should take ' +
        str(fuzzing_time_seconds / 60) + ' minutes')
    TestRun.executor.run(f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
                         '"rootfs/bin/iotrace --get-trace-statistics -p '
                         f'{IotracePlugin.get_latest_trace_path()}" --one-job')
    output = wait_for_completion(fuzzing_time_seconds, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    TestRun.executor.run_expect_success(f'rm -rf {repo_path}/afl-i')
    detect_crashes(output, "trace-file")
def test_fuzz_config():
    fuzzing_time_seconds = 10 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Create patch file for redirecting fuzzed stdin to config file path
    new_patch_path: str = f'{iotrace.working_dir}/redirect_to_config.patch'
    create_patch_redirect_fuzz_to_file(
        f'{repo_path}/rootfs/etc/octf/octf.conf', new_patch_path)

    # Install iotrace locally with AFL support and redirect patch
    install_iotrace_with_afl_support(new_patch_path, [
        'modules/open-cas-telemetry-framework', 'modules/test-framework',
        'source/kernel'
    ])

    TestRun.executor.run_expect_success(
        f'cd {repo_path} && mkdir -p afl-i afl-o')
    # Use config as seed to be mutated
    TestRun.executor.run_expect_success(
        f'cp {repo_path}/rootfs/etc/octf/octf.conf'
        f' {repo_path}/afl-i/case0')

    TestRun.LOGGER.info('Starting fuzzing octf.conf. This should take ' +
                        str(fuzzing_time_seconds / 60) + ' minutes')

    TestRun.LOGGER.info("Trying 'list-traces' command")
    TestRun.executor.run(f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
                         '"rootfs/bin/iotrace -L" --one-job')
    output = wait_for_completion(fuzzing_time_seconds / 2, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    detect_crashes(output, "octf-config")

    TestRun.LOGGER.info("Trying 'get-trace-repository-path' command")
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh '
        '"rootfs/bin/iotrace --get-trace-repository" --one-job')
    output = wait_for_completion(fuzzing_time_seconds / 2, repo_path)
    TestRun.executor.run(
        f'cd {repo_path} && ./tests/security/fuzzy/fuzz.sh clean')
    TestRun.executor.run_expect_success(f'rm -rf {repo_path}/afl-i')
    detect_crashes(output, "octf-config")
示例#5
0
def test_fuzz_procfs():
    # For simplicity we start one non-instrumented iotrace instance
    # and fuzz proc files using afl with -n flag (dumb fuzzing)
    fuzzing_time_seconds = 15 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Reset dmesg so we don't accidentaly grep old kernel panics
    TestRun.executor.run_expect_success('dmesg -c')

    # Procfs files and their initial seed
    fuzzed_files = {"/proc/iotrace/add_device": "/dev/sdb",
                    "/proc/iotrace/remove_device": "/dev/sdb",
                    "/proc/iotrace/size": "1024"}

    # Start tracing, we start it using procfs interface by putting traced
    # device path, buffer size, and mmaping (using fio with mmap engine)
    # consumer header procfile. This is because procfiles may have a limit
    # on applications which mmap them, and iotrace -S may block other mmaps
    disk = TestRun.dut.disks[0].system_path
    TestRun.executor.run_expect_success(f'modprobe iotrace')
    TestRun.executor.run_expect_fail(f'echo {disk} > /proc/iotrace/add_device')
    TestRun.executor.run_expect_success(f'echo 1024 > /proc/iotrace/size')
    fio_pid = TestRun.executor.run_in_background(f'fio --name=job --direct=0 --ioengine=mmap '
                                                 f'--filename=/proc/iotrace/consumer_hdr.0 '
                                                 f"--buffer_pattern=\\'/dev/urandom\\' "
                                                 f'--time_based --runtime=30s --bs=4k '
                                                 f'--iodepth=128 --rw=randwrite')
    time.sleep(5)
    TestRun.executor.run_expect_success(f'echo {disk} > /proc/iotrace/add_device')

    # Also start some workload on traced device to generate trace traffic
    workload_pid = TestRun.executor.run_in_background(f'fio --direct=1'
                                                 f'--filename={disk} '
                                                 f'--time_based --runtime=24h --bs=4k '
                                                 f'--iodepth=1 --rw=randwrite --name=job2 --size=4k')

    for procfile, seed in fuzzed_files.items():
        # Create patch file for redirecting fuzzed stdin to proc file
        new_patch_path: str = f'{iotrace.working_dir}/redirect_to_procfile.patch'
        create_patch_redirect_fuzz_to_file(f'{procfile}', new_patch_path)

        # Install iotrace locally with AFL support and redirect patch
        install_iotrace_with_afl_support(new_patch_path,
                                         ['modules/open-cas-telemetry-framework', 'modules/test-framework', 'source/kernel'])

        TestRun.executor.run_expect_success(
            f'cd {repo_path} && mkdir -p afl-i afl-o')
        # Add input seed which shall be mutated
        TestRun.executor.run_expect_success(f'cd {repo_path} && echo {seed} > afl-i/case0')

        TestRun.LOGGER.info(f'Starting fuzzing {procfile} This should take ' +
                            str(fuzzing_time_seconds / 60 / len(fuzzed_files))
                            + ' minutes')

        # May need to set CPU to performance mode beforehand:
        # cd /sys/devices/system/cpu
        # echo performance | tee cpu*/cpufreq/scaling_governor
        TestRun.executor.run_in_background(f'cd {repo_path} && screen -S master -d -m &&'
                                           f'screen -S master -X stuff "afl-fuzz -n -i '
                                           f'afl-i -o afl-o {repo_path}/rootfs/bin/iotrace -H\n"')
        elapsed = 0
        start_time = time.time()
        while elapsed < fuzzing_time_seconds / len(fuzzed_files):
            output = TestRun.executor.run(f'dmesg | grep -A 40 -B 10 "Call Trace"')
            if output.exit_code == 0:
                save_fuzzing_output(f'{repo_path}/afl-o', f'procfs-{procfile.split("/")[-1]}')
                TestRun.fail(f'Kernel BUGs during fuzzing {procfile} were found:\n'
                             f'{output.stdout}')

            time.sleep(5)
            current_time = time.time()
            elapsed = current_time - start_time

        TestRun.executor.run_expect_success('killall afl-fuzz && screen -X -S master kill')

    # Stop tracing
    TestRun.executor.run(f'kill {fio_pid}')
    TestRun.executor.run_expect_success(f'kill {workload_pid}')
    TestRun.executor.run_expect_success(f'rm -rf {repo_path}/afl-i')
def test_fuzz_procfs():
    # For simplicity we start one non-instrumented iotrace instance
    # and fuzz proc files using afl with -n flag (dumb fuzzing)
    fuzzing_time_seconds = 15 * 60
    iotrace: IotracePlugin = TestRun.plugins['iotrace']

    repo_path: str = f"{iotrace.working_dir}/slit-afl"

    # Make sure AFL is installed
    if not is_afl_installed():
        install_afl()

    # Instruct the system to output coredumps as files instead of sending them
    # to a specific crash handler app
    TestRun.LOGGER.info('Setting up system for fuzzing')
    TestRun.executor.run_expect_success(
        'echo core > /proc/sys/kernel/core_pattern')
    TestRun.executor.run_expect_success(
        f'cd {repo_path} && mkdir -p afl-i afl-o')

    # Procfs files and their initial seed
    fuzzed_files = {
        "/proc/iotrace/add_device": "/dev/sdb",
        "/proc/iotrace/remove_device": "/dev/sdb",
        "/proc/iotrace/size": "1024"
    }

    # Start tracing, we start it using procfs interface by putting traced
    # device path, buffer size, and mmaping (using fio with mmap engine)
    # consumer header procfile. This is because procfiles may have a limit
    # on applications which mmap them, and iotrace -S may block other mmaps
    disk = TestRun.dut.disks[0].system_path
    TestRun.executor.run_expect_success(
        f'echo {disk} > /proc/iotrace/add_device')
    TestRun.executor.run_expect_success(f'echo 1024 > /proc/iotrace/size')
    fio_pid = TestRun.executor.run_in_background(
        f'fio --name=job --direct=0 --ioengine=mmap '
        f'--filename=/proc/iotrace/consumer_hdr.0 '
        f"--buffer_pattern=\\'/dev/urandom\\' "
        f'--time_based --runtime=30s --bs=4k '
        f'--iodepth=128 --rw=randwrite')

    # Also start some workload on traced device to generate trace traffic
    workload_pid = TestRun.executor.run_in_background(
        f'fio --direct=1'
        f'--filename={disk} '
        f'--time_based --runtime=24h --bs=4k '
        f'--iodepth=1 --rw=randwrite')

    for procfile, seed in fuzzed_files.items():
        # Create patch file for redirecting fuzzed stdin to proc file
        new_patch_path: str = f'{iotrace.working_dir}/redirect_to_procfile.patch'
        create_patch_redirect_fuzz_to_file(f'{procfile}', new_patch_path)

        # Install iotrace locally with AFL support and redirect patch
        install_iotrace_with_afl_support(new_patch_path)

        # Add input seed which shall be mutated
        TestRun.executor.run_expect_success(
            f'cd {repo_path} && echo {seed} > afl-i/case0')

        TestRun.LOGGER.info(f'Starting fuzzing {procfile} This should take ' +
                            str(fuzzing_time_seconds / 60 /
                                len(fuzzed_files)) + ' minutes')

        TestRun.executor.run_in_background(
            f'cd {repo_path} && screen -S master -d -m &&'
            f'screen -S master -X stuff "afl-fuzz -n -i '
            f'afl-i -o afl-o {repo_path}/rootfs/bin/iotrace -H\n"')
        elapsed = 0
        start_time = time.time()
        while elapsed < fuzzing_time_seconds / len(fuzzed_files):
            output = TestRun.executor.run(f'dmesg | grep -A 20 "Call Trace"')
            if output.exit_code == 0:
                save_fuzzing_output(f'{repo_path}/afl-o')
                TestRun.executor.run_expect_success('dmesg -c')
                TestRun.fail('Kernel BUGs during fuzzing procfs were found:\n'
                             f'{output.stdout}')

            time.sleep(5)
            current_time = time.time()
            elapsed = current_time - start_time

        TestRun.executor.run_expect_success(
            'killall afl-fuzz && screen -X -S master kill')

    # Stop tracing
    TestRun.executor.run_expect_success(f'kill {fio_pid}')
    TestRun.executor.run_expect_success(f'kill {workload_pid}')