예제 #1
0
    def generate_and_run_mutants(self, maxDepth, maxAssert):
        smt_Object = smtObject(file_path=self.minimized_file_path,
                               path_to_mutant_folder=self.temp_dir)
        smt_Object.check_satisfiability(timeout=120)
        signal = generate_mutants(smt_Object=smt_Object,
                                  path_to_directory=self.temp_dir,
                                  maxDepth=maxDepth,
                                  maxAssert=maxAssert,
                                  seed=self.seed,
                                  theory=self.theory,
                                  fuzzing_parameters=self.fuzzing_parameters)
        mutant_file_paths = get_mutant_paths(self.temp_dir)
        if self.incremental:
            mutant_file_paths.sort()
            insert_pushes_pops(mutant_file_paths, self.randomness)
        for mutant_file_path in mutant_file_paths:
            if self.check_sat_using is not None:
                add_check_sat_using(mutant_file_path, self.check_sat_using)
        # run mutants
        unsat_mutants = []
        running_start = time.time()
        print(colored("Running Mutants.... ", "green", attrs=["bold"]))
        for mutant in mutant_file_paths:
            output = solver_runner(
                solver_path=self.solverbin,
                smt_file=mutant,
                temp_core_folder=self.temp_dir,
                timeout=self.fuzzing_parameters["solver_timeout"],
                incremental="yes" if self.incremental else "no",
                solver=self.solver)

            self.number_of_queries += 1
            if output == "unsat":
                unsat_mutants.append(mutant)

            # stop running mutants after 30 mins
            current_time = time.time()
            if (int(current_time - running_start) >
                    self.fuzzing_parameters["mutant_running_timeout"]):
                print(
                    colored(">>> TIMEOUT WHILE RUNNING THE MUTANTS <<<< ",
                            "red",
                            attrs=["bold"]))
                break

        if len(unsat_mutants) > 0:
            min_lines = self.get_number_of_lines(unsat_mutants[0])
            min_mutant = unsat_mutants[0]
            for mutant in unsat_mutants[1:]:
                if self.get_number_of_lines(mutant) < min_lines:
                    min_lines = self.get_number_of_lines(mutant)
                    min_mutant = mutant
            print(colored("Found a failing example", "green", attrs=["bold"]))
            return True, min_mutant
        print(
            colored("Could not find a failing example with these parameters",
                    "red",
                    attrs=["bold"]))
        return False, ""
예제 #2
0
    def run_mutants_in_a_thread(path_to_temp_core_directory, signal,
                                seed_file_number, seed_file_path,
                                incrementality, solver, fuzzing_parameters):
        mutant_file_paths = get_mutant_paths(path_to_temp_core_directory)
        mutant_file_paths.sort()
        if len(mutant_file_paths) > 0:
            if signal == 1:
                print(
                    colored(
                        "\tExperienced timeout while exporting mutants. But we still were able to export some",
                        "magenta",
                        attrs=["bold"]))
            print("####### RUNNING MUTANTS")
            start_time = time.time()
            for i, mutant_path in enumerate(mutant_file_paths):
                output = solver_runner(
                    solver_path=parsedArguments["solverbin"],
                    smt_file=mutant_path,
                    temp_core_folder=path_to_temp_core_directory,
                    timeout=ALL_FUZZING_PARAMETERS["solver_timeout"],
                    incremental=incrementality,
                    solver=solver)
                print("[" + parsedArguments["solver"] + "]\t" + "[core: " +
                      str(core) + "]\t",
                      end="")
                print("[seed_file: " + str(seed_file_number) + "]\t\t" + "[" +
                      str(i + 1) + "/" + str(len(mutant_file_paths)) + "]\t\t",
                      end="")
                print("[" + parsedArguments["theory"] + "]\t", end="")

                if output == "sat":
                    print(colored(output, "green", attrs=["bold"]))
                elif output == "unsat":
                    print(colored(output, "red", attrs=["bold"]))
                    print(mutant_path)
                    print(
                        colored("SOUNDNESS BUG",
                                "white",
                                "on_red",
                                attrs=["bold"]))
                    print("SEED = " + str(SEED))
                    # Handle unsoundness
                    record_soundness(home_directory=config["home"],
                                     seed_file_path=seed_file_path,
                                     buggy_mutant_path=mutant_path,
                                     seed=SEED,
                                     mutant_number=i,
                                     seed_theory=parsedArguments["theory"],
                                     fuzzing_parameters=fuzzing_parameters)
                    print(
                        colored("Time to bug: ", "magenta", attrs=["bold"]) +
                        str(time.time() - start_time))
                    print(
                        colored(
                            "Iterations to bug: ", "magenta", attrs=["bold"]) +
                        str(i + 1))
                elif output == "error":
                    print(colored(output, "white", "on_red", attrs=["bold"]))
                else:
                    print(colored(output, "yellow", attrs=["bold"]))
                os.remove(mutant_path)  # remove mutant when processed
예제 #3
0
def run_storm(parsedArguments, core, SEED, wait, reproduce, rq3,
              fuzzing_params):
    def run_mutants_in_a_thread(path_to_temp_core_directory, signal,
                                seed_file_number, seed_file_path,
                                incrementality, solver, fuzzing_parameters):
        mutant_file_paths = get_mutant_paths(path_to_temp_core_directory)
        mutant_file_paths.sort()
        if len(mutant_file_paths) > 0:
            if signal == 1:
                print(
                    colored(
                        "\tExperienced timeout while exporting mutants. But we still were able to export some",
                        "magenta",
                        attrs=["bold"]))
            print("####### RUNNING MUTANTS")
            start_time = time.time()
            for i, mutant_path in enumerate(mutant_file_paths):
                output = solver_runner(
                    solver_path=parsedArguments["solverbin"],
                    smt_file=mutant_path,
                    temp_core_folder=path_to_temp_core_directory,
                    timeout=ALL_FUZZING_PARAMETERS["solver_timeout"],
                    incremental=incrementality,
                    solver=solver)
                print("[" + parsedArguments["solver"] + "]\t" + "[core: " +
                      str(core) + "]\t",
                      end="")
                print("[seed_file: " + str(seed_file_number) + "]\t\t" + "[" +
                      str(i + 1) + "/" + str(len(mutant_file_paths)) + "]\t\t",
                      end="")
                print("[" + parsedArguments["theory"] + "]\t", end="")

                if output == "sat":
                    print(colored(output, "green", attrs=["bold"]))
                elif output == "unsat":
                    print(colored(output, "red", attrs=["bold"]))
                    print(mutant_path)
                    print(
                        colored("SOUNDNESS BUG",
                                "white",
                                "on_red",
                                attrs=["bold"]))
                    print("SEED = " + str(SEED))
                    # Handle unsoundness
                    record_soundness(home_directory=config["home"],
                                     seed_file_path=seed_file_path,
                                     buggy_mutant_path=mutant_path,
                                     seed=SEED,
                                     mutant_number=i,
                                     seed_theory=parsedArguments["theory"],
                                     fuzzing_parameters=fuzzing_parameters)
                    print(
                        colored("Time to bug: ", "magenta", attrs=["bold"]) +
                        str(time.time() - start_time))
                    print(
                        colored(
                            "Iterations to bug: ", "magenta", attrs=["bold"]) +
                        str(i + 1))
                elif output == "error":
                    print(colored(output, "white", "on_red", attrs=["bold"]))
                else:
                    print(colored(output, "yellow", attrs=["bold"]))
                os.remove(mutant_path)  # remove mutant when processed

    """
        Initalizations
    """
    time.sleep(wait)
    print("Running storm on a core")
    temp_directory = os.path.join(config["home"], "temp")
    path_to_temp_core_directory = os.path.join(temp_directory,
                                               parsedArguments["server"],
                                               "core_" + core)
    create_server_core_directory(temp_directory, parsedArguments["server"],
                                 core)
    seed_file_paths = []

    global ALL_FUZZING_PARAMETERS
    if not reproduce:
        # normal mode
        ALL_FUZZING_PARAMETERS = get_parameters_dict(replication_mode=False,
                                                     bug_number=None)
        path_to_theory = os.path.join(parsedArguments["benchmark"],
                                      parsedArguments["theory"])
        if not os.path.exists(path_to_theory):
            print(colored("Theory not found in the benchmarks folder", "red"))
            return 1
        seed_file_paths = get_all_smt_files_recursively(path_to_theory)
    else:
        # FSE2020 bugs reproduction mode
        # Get the path to the seed file
        ALL_FUZZING_PARAMETERS = get_parameters_dict(
            replication_mode=True, bug_number=parsedArguments["reproduce"])
        path_to_seed_file = os.path.join(config["home"], "storm", "fse_repl",
                                         parsedArguments["reproduce"],
                                         "seed.smt2")
        print("Path to seed file for this bug = " + path_to_seed_file)
        seed_file_paths.append(path_to_seed_file)
        parsedArguments["theory"] = ALL_FUZZING_PARAMETERS["theory"]

    randomness = Randomness(SEED)
    randomness.shuffle_list(seed_file_paths)
    # run the file and see if it is SAT or UNSAT
    for i, file in enumerate(seed_file_paths):
        # Refresh core directory
        refresh_directory(path_to_temp_core_directory)
        incrementality = randomness.random_choice(
            ALL_FUZZING_PARAMETERS["incremental"])
        print("####### [" + str(i) + "] seed: ", end="")
        smt_Object = smtObject(
            file_path=file, path_to_mutant_folder=path_to_temp_core_directory)
        if not smt_Object.get_validity():
            print(colored("Was not able to parse the smt file", "red"))
            return 1

        smt_Object.check_satisfiability(
            timeout=ALL_FUZZING_PARAMETERS["solver_timeout"])
        if smt_Object.get_orig_satisfiability() == "timeout":
            continue
        if not smt_Object.get_validity():
            continue

        max_depth = ALL_FUZZING_PARAMETERS["max_depth"]
        max_assert = ALL_FUZZING_PARAMETERS["max_assert"]

        # Generate all mutants at once for this file in a thread with a timeout
        signal = generate_mutants(
            smt_Object=smt_Object,
            path_to_directory=path_to_temp_core_directory,
            maxDepth=max_depth,
            maxAssert=max_assert,
            seed=SEED,
            theory=parsedArguments["theory"],
            fuzzing_parameters=ALL_FUZZING_PARAMETERS)
        mutant_file_paths = get_mutant_paths(path_to_temp_core_directory)

        if len(mutant_file_paths) == 0:
            print(colored("NO MUTANTS GENERATED", "red", attrs=["bold"]))
            continue

        # Incremental setting apply to all mutants of a file
        print("####### Setting incrementality with prob: " +
              colored(str(ALL_FUZZING_PARAMETERS["incremental"]),
                      "yellow",
                      attrs=["bold"]))
        print("####### Incrementality: ", end="")
        if incrementality == "yes":
            print(colored("YES", "green", attrs=["bold"]))
            mutant_file_paths.sort()
            insert_pushes_pops(mutant_file_paths, randomness)
        else:
            print(colored("NO", "red", attrs=["bold"]))

        print("####### Adding check-sat-using options with prob: " +
              colored(str(ALL_FUZZING_PARAMETERS["check_sat_using"]),
                      "yellow",
                      attrs=["bold"]))
        for mutant_file_path in mutant_file_paths:
            if randomness.random_choice(
                    ALL_FUZZING_PARAMETERS["check_sat_using"]
            ) == "yes" and parsedArguments["solver"] == "z3":
                check_sat_using_option = randomness.random_choice(
                    ALL_FUZZING_PARAMETERS["check_sat_using_options"])
                add_check_sat_using(mutant_file_path, check_sat_using_option)

        # If we are in bug repoduction mode, copy the buggy mutant to the bug folder in fse replication folder
        if reproduce:
            print("copying the buggy mutant")
            buggy_mutant = [
                i for i in mutant_file_paths
                if i.find(ALL_FUZZING_PARAMETERS["buggy_mutant"]) != -1
            ][0]
            path_to_bug_directory_in_fse_repl = os.path.join(
                config["home"], "storm", "fse_repl",
                parsedArguments["reproduce"])
            print(
                colored("copying the buggy mutant to: ",
                        "yellow",
                        attrs=["bold"]) + path_to_bug_directory_in_fse_repl)
            shutil.copy2(buggy_mutant, path_to_bug_directory_in_fse_repl)
            if parsedArguments["solverbin"] is None:
                print(
                    "Skipping mutant running since --solverbin and --solver flags are None"
                )
                continue

        # Spawn a new process and run mutants
        process = multiprocessing.Process(
            target=run_mutants_in_a_thread,
            args=(path_to_temp_core_directory, signal, i, file, incrementality,
                  parsedArguments["solver"], ALL_FUZZING_PARAMETERS))
        process.start()
        process.join(ALL_FUZZING_PARAMETERS["mutant_running_timeout"])
        if process.is_alive():
            process.terminate()
            print(
                colored("TIMEOUT WHILE RUNNING THE MUTANTS",
                        "red",
                        attrs=["bold"]))
            time.sleep(
                ALL_FUZZING_PARAMETERS["solver_timeout"]
            )  # Wait for the solver to finish processing the last file before deleting the temp dir
        refresh_directory(path_to_temp_core_directory)