def build_docker_image(config): """Creates docker image containing DUT to fuzz.""" if not config.args.silent: print(LINE_SEP) print("Building Docker image to fuzz %s ..." % config.toplevel) print(LINE_SEP) # Set Dockerfile path if config.soc == "other": dockerfile_path = "%s/hw/other/%s" % (config.root_path, config.toplevel) else: dockerfile_path = "%s/hw/%s" % (config.root_path, config.soc) # Build command cmd = [ "docker", "build", "--build-arg", "TOPLEVEL=%s" % config.toplevel, "--build-arg", "TB_TYPE=%s" % config.tb_type, "--build-arg", "FUZZER=%s" % config.fuzzer, "--build-arg", "VERSION=%s" % config.version, "-t", config.docker_image, dockerfile_path ] error_str = "ERROR: image build FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("IMAGE BUILD SUCCESSFUL -- Done!"))
def delete_data_in_gcs(config): """Deletes data in the configured GCS bucket for a fuzzing session.""" sub_cmd = [ "gsutil", "rm", "gs://%s-%s/%s/**" % (config.gcp_params["project_id"], config.gcp_params["data_bucket"], config.experiment_name) ] error_str = "ERROR: deleting existing data. Terminating Experiment!" run_cmd(sub_cmd, error_str, silent=config.args.silent)
def push_docker_image_to_gcr(config): """Pushes docker image to GCR if it does not exist there yet.""" if not config.args.silent: print(LINE_SEP) print("Pushing Docker image to GCR ...") print(LINE_SEP) if config.args.update or not check_if_docker_image_exists_in_gcr(config): cmd = ["docker", "push", config.docker_image] error_str = "ERROR: pushing image to GCR FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("IMAGE PUSH SUCCESSFUL -- Done!")) else: if not config.args.silent: print(yellow("IMAGE ALREADY EXISTS IN GCR -- Done!"))
def build_docker_image(config): """Creates docker image containing DUT to fuzz.""" if not config.args.silent: print(LINE_SEP) print("Building Docker image to fuzz %s ..." % config.toplevel) print(LINE_SEP) cmd = [ "docker", "build", "--build-arg", "FUZZER=%s" % config.fuzzer, "--build-arg", "VERSION=%s" % config.version, "-t", config.docker_image, "%s/hw/%s" % (config.root_path, config.toplevel) ] error_str = "ERROR: image build FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("IMAGE BUILD SUCCESSFUL -- Done!"))
def push_vm_management_scripts_to_gcs(config): """Pushes VM management (startup/shutdown scripts to GCS.""" if not config.args.silent: print(LINE_SEP) print("Copying VM management script to GCS ...") print(LINE_SEP) cmd = [ "gsutil", "cp", "%s/infra/hwfp/%s" % (config.root_path, config.gcp_params["startup_script"]), "gs://%s-%s/%s" % (config.gcp_params["project_id"], config.gcp_params["vm_management_bucket"], config.gcp_params["startup_script"]) ] error_str = "ERROR: pushing scripts to GCS FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("COPY SUCCESSFUL -- Done!"))
def _run_gsutil_cmd(gs_util_cmd): run_cmd(gs_util_cmd, "ERROR: cannot copy data from GCS.", silent=True, fail_silent=True)
def run_docker_container_on_gce(config): """Runs a Docker container to fuzz the DUT on a Google Compute Engine VM.""" # ***IMPORTANT: check how many VM instances currently up before launching*** launch_vm = False while not launch_vm: # if above under $$$ threshold, create VM instance, else wait if check_num_active_vm_instances(config) < config.args.max_vm_instances: launch_vm = True else: time.sleep(config.args.vm_launch_wait_time_s) # wait before trying again # Launch fuzzing container on VM if not config.args.silent: print(LINE_SEP) print("Launching GCE VM to fuzz %s ..." % config.toplevel) print(LINE_SEP) cmd = [ "gcloud", "compute", "--project=%s" % config.gcp_params["project_id"], "instances", "create-with-container", config.experiment_name, "--container-image", config.docker_image, "--container-stdin", "--container-tty", "--container-privileged", "--container-restart-policy", config.gcp_params["container_restart_policy"], "--zone=%s" % config.gcp_params["zone"], "--machine-type=%s" % config.gcp_params["machine_type"], "--boot-disk-size=%s" % config.gcp_params["boot_disk_size"], "--scopes=%s" % config.gcp_params["scopes"], "--metadata=startup-script-url=gs://%s-%s/%s" % (config.gcp_params["project_id"], config.gcp_params["vm_management_bucket"], config.gcp_params["startup_script"]), ] # Open shell debugging if config.manual: cmd.append("--container-command=/bin/bash") # Set environment variables for general configs cmd.extend(["--container-env", "%s=%s" % ("TOPLEVEL", config.toplevel)]) cmd.extend(["--container-env", "%s=%s" % ("VERSION", config.version)]) cmd.extend(["--container-env", "%s=%s" % ("TB_TYPE", config.tb_type)]) cmd.extend(["--container-env", "%s=%s" % ("TB", config.tb)]) cmd.extend(["--container-env", "%s=%s" % ("FUZZER", config.fuzzer)]) cmd.extend( ["--container-env", "%s=%s" % ("INSTRUMENT_DUT", config.instrument_dut)]) cmd.extend( ["--container-env", "%s=%s" % ("INSTRUMENT_TB", config.instrument_tb)]) cmd.extend([ "--container-env", "%s=%s" % ("INSTRUMENT_VLTRT", config.instrument_vltrt) ]) cmd.extend(["--container-env", "%s=%s" % ("RUN_ON_GCP", config.run_on_gcp)]) # Set environment variables for Verilator/HDL-generator/fuzzer params for params in config.env_var_params: for param, value in params.items(): if value is not None: cmd.extend(["--container-env", "%s=%s" % (param.upper(), value)]) # launch container in VM instance error_str = "ERROR: launching VM on GCE FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("VM LAUNCH SUCCESSFUL -- Done!"))
def run_docker_container_locally(config, exp_data_path): """Runs a Docker container to fuzz the DUT on the local machine.""" if not config.args.silent: print(LINE_SEP) print("Running Docker container to fuzz %s ..." % config.toplevel) print(LINE_SEP) cmd = [ "docker", "run", "-it", "--rm", "--security-opt", "seccomp=unconfined", "--log-driver=%s" % config.args.log_driver, "--name", config.experiment_name, ] # Set environment variables for general configs cmd.extend(["-e", "%s=%s" % ("TOPLEVEL", config.toplevel)]) cmd.extend(["-e", "%s=%s" % ("VERSION", config.version)]) cmd.extend(["-e", "%s=%s" % ("TB_TYPE", config.tb_type)]) cmd.extend(["-e", "%s=%s" % ("TB", config.tb)]) cmd.extend(["-e", "%s=%s" % ("FUZZER", config.fuzzer)]) cmd.extend(["-e", "%s=%s" % ("INSTRUMENT_DUT", config.instrument_dut)]) cmd.extend(["-e", "%s=%s" % ("INSTRUMENT_TB", config.instrument_tb)]) cmd.extend(["-e", "%s=%s" % ("INSTRUMENT_VLTRT", config.instrument_vltrt)]) cmd.extend(["-e", "%s=%s" % ("RUN_ON_GCP", config.run_on_gcp)]) # Set environment variables for Verilator/HDL-generator/fuzzer params for params in config.env_var_params: for param, value in params.items(): if value is not None: cmd.extend(["-e", "%s=%s" % (param.upper(), value)]) # Mount volumes for output data cmd.extend( ["-v", "%s/logs:/src/hw/%s/logs" % (exp_data_path, config.toplevel)]) cmd.extend( ["-v", "%s/out:/src/hw/%s/out" % (exp_data_path, config.toplevel)]) # If manual mode, mount src code for development/debugging if config.manual: cmd.extend( ["-v", "%s/%s:/src/hw/hwfutils" % (config.root_path, HWFUTILS_PATH)]) cmd.extend(["-v", "%s/%s:/src/hw/tb" % (config.root_path, SHARED_TB_PATH)]) cmd.extend([ "-v", "%s/hw/%s:/src/hw/%s" % (config.root_path, config.toplevel, config.toplevel) ]) cmd.extend([ "-v", "%s/infra/base-sim/common.mk:/src/hw/common.mk" % config.root_path ]) cmd.extend( ["-v", "%s/infra/base-sim/exe.mk:/src/hw/exe.mk" % config.root_path]) for script in [ "run", "run-kcov", "run-llvm-cov", "run-vlt-cov", "set_hwf_isa.sh", "cpp-verilator-sim", ]: cmd.extend([ "-v", "%s/infra/base-sim/scripts/%s:/scripts/%s" % (config.root_path, script, script) ]) if config.fuzzer == "afl" or config.fuzzer == "afl-term-on-crash": for script in ["compile", "fuzz"]: cmd.extend([ "-v", "%s/infra/base-afl/%s:/scripts/%s" % (config.root_path, script, script) ]) # Set target Docker image and run cmd.extend(["-t", config.docker_image]) # If manual mode, start shell if config.manual: cmd.append("/bin/bash") error_str = "ERROR: container run FAILED. Terminating experiment!" run_cmd(cmd, error_str, silent=config.args.silent) if not config.args.silent: print(green("CONTAINER RUN SUCCESSFUL -- Done!"))
def delete_gce_vm(config): """Delete active Google Compute Engine VM running the same experiment.""" cmd = ["gcloud", "compute", "instances", "delete", config.experiment_name] error_str = "ERROR: cannot delete GCE VM (%s). Aborting!" % ( config.experiment_name) run_cmd(cmd, error_str, silent=config.args.silent)