def run_tgt(self, tc, img): env = self.cfg.get_env(persist=False) cmd = list(self.cfg.tgtcmd) _, cmd = nh.set_img_path(cmd, img, self.cfg) fd, tempf = tempfile.mkstemp(prefix='pmfuzz-gcov-run-') os.close(fd) if self.verbose: printv('target run:') printv('%20s : %s' % ('env', str(env))) printv('%20s : %s' % ('input', tc)) printv('%20s : %s' % ('output', tempf)) printv('%20s : %s' % ('cmd', ' '.join(cmd))) with open(tc, 'r') as stdin, open(tempf, 'w') as stdout: exec_shell( cmd=cmd, stdin=stdin, stdout=stdout, stderr=stdout, env=env, wait=True, )
def remove_captures(self, tracefile): fd, result_f = tempfile.mkstemp(prefix='pmfuzz-lcov-out-') os.close(fd) lcov_bin = ['lcov'] lcov_opts = ['--no-checksum', '-r'] + [tracefile] lcov_opts += ['/usr/include/*'] lcov_scd = [] lcov_out = ['--output-file', result_f] lcov_cmd = lcov_bin + lcov_opts + lcov_scd + lcov_out fd, log_f = tempfile.mkstemp(prefix='pmfuzz-lcov-log-') os.close(fd) if self.verbose: printv('remove /usr/include:') printv('%20s : %s' % ('env', str({}))) printv('%20s : %s' % ('cmd', ' '.join(lcov_cmd))) printv('%20s : %s' % ('output', log_f)) with open(log_f, 'w') as log_obj: exec_shell( lcov_cmd, stdin=None, stdout=log_obj, stderr=log_obj, env={}, wait=True, ) return result_f
def reset_counters(self): fd, result_f = tempfile.mkstemp(prefix='pmfuzz-lcov-out-') os.close(fd) lcov_bin = ['lcov'] lcov_opts = self.cfg['lcov']['options'] + ['-z'] lcov_scd = ['--directory'] + self.cfg['lcov']['source_code_dirs'] lcov_out = ['--output-file', result_f] lcov_cmd = lcov_bin + lcov_opts + lcov_scd + lcov_out fd, log_f = tempfile.mkstemp(prefix='pmfuzz-lcov-log-') os.close(fd) if self.verbose: printv('counters reset:') printv('%20s : %s' % ('env', str({}))) printv('%20s : %s' % ('cmd', ' '.join(lcov_cmd))) printv('%20s : %s' % ('output', log_f)) with open(log_f, 'w') as log_obj: exec_shell( lcov_cmd, stdin=None, stdout=log_obj, stderr=log_obj, env={}, wait=True, ) return result_f
def capture(self): fd, result_f = tempfile.mkstemp(prefix='pmfuzz-lcov-out-') os.close(fd) lcov_bin = ['lcov'] lcov_opts = self.cfg['lcov']['options'] + ['-c'] lcov_scd = ['--directory'] + self.cfg['lcov']['source_code_dirs'] lcov_out = ['--output-file', result_f] lcov_cmd = lcov_bin + lcov_opts + lcov_scd + lcov_out fd, log_f = tempfile.mkstemp(prefix='pmfuzz-lcov-log-') os.close(fd) if self.verbose: printv('lcov run:') printv('%20s : %s' % ('env', str({}))) printv('%20s : %s' % ('cmd', ' '.join(lcov_cmd))) printv('%20s : %s' % ('output', log_f)) with open(log_f, 'w') as log_obj: exec_shell( lcov_cmd, stdin=None, stdout=log_obj, stderr=log_obj, env={}, wait=True, ) if self.verbose: printv('Coverage information written to ' + result_f) f_count = 0 with open(result_f, 'r') as obj: for line in obj: tokens = line.split(':') if tokens[0] == 'FNDA': cur_count = int(tokens[1].split(',')[0]) if cur_count > 0: f_count += 1 printv('Total %d functions hit' % f_count) return result_f
def run_failure_inj(cfg, tgtcmd, imgpath, testcase_f, clean_name, create, verbose=False): """ @brief Run failure injection on an image @param create If true, inject the failure to the process of creating the image @return None""" if not create and not os.path.isfile(imgpath): abort('Image path %s does not exist' % imgpath) env, cmd = gen_failure_inj_cmd(cfg, cfg.tgtcmd, imgpath, create, verbose) env.update({"FI_IMG_SUFFIX": clean_name.replace('.testcase', '')}) if verbose: printv('Failure Injection:') printv('%20s : %s' % ('env', str(env))) printv('%20s : %s' % ('cmd', ' '.join(cmd))) printv('%20s : %s' % ('stdin', testcase_f)) fd, out_file = tempfile.mkstemp(prefix='pmfuzz-img-gen-out-') printv('Redirecting output to ' + out_file) exit_code = None with open(out_file, 'w') as stdout, open(testcase_f, 'r') as stdin: exit_code = exec_shell( cmd=cmd, stdin=stdin, stdout=stdout, stderr=subprocess.STDOUT, env=env, wait=True, timeout= 30 # Set a generous timeout of 30 seconds so things don't crash ) os.close(fd) descr_str, success = translate_exit_code(exit_code) if not success: abort('Failure injection for pid %d failed: %s' \ % (os.getpid(), descr_str))
def test_img_gen(self, imgpath): """ @brief Tests the process of creating a new image with the testcase by checking return code of the target @param imgpath str representing the complete path of the image to test, the path should not exist @return bool value indicating success """ # Create a tempfile for writing run output fd, tmp = tempfile.mkstemp(prefix='pmfuzz-test-img-output-') os.close(fd) tgtcmd_loc = list(self.cfg.tgtcmd) imgpath, tgtcmd_loc = nh.set_img_path(tgtcmd_loc, imgpath, self.cfg) env = self.cfg.get_env(persist=False) if self.verbose: printv('Writing run output to ' + tmp) success, exit_code = None, None with open(tmp, 'w') as out: with open(self.testcase_f, 'r') as testcase_obj: exit_code = exec_shell( cmd = tgtcmd_loc, stdin = testcase_obj, stdout = out, stderr = subprocess.STDOUT, env = env, wait = True ) code_desc, success = translate_exit_code(exit_code) if not success and self.verbose: printv('Image failed.') if success == None: abort('Test run failed, unable to check image.') return success, exit_code, tgtcmd_loc, env
def gen_img(self, dest_dir, compress_img=True, img_path=None): """ @brief Generate image for a testcase file @param testcase_f str that points to the testcase to use for generation @param dest_dir str Directory to store the resulting image @param tgtcmd List of str for the command for running the target prog @param cfg Config for setting up the target process' environment @return None """ testcase_f = self.testcase_f cfg = self.cfg verbose = self.verbose tgtcmd = cfg.tgtcmd tgtcmd_loc = None if img_path == None: img_name = path.basename(nh.get_metadata_files(testcase_f)['pm_pool']) # Get the command for generating the image img_path, tgtcmd_loc = nh.set_img_name(tgtcmd, img_name, cfg) abort_if(img_path=='', 'Unable to parse image path, tgtcmd=' + \ str(tgtcmd) + ', img_name=' + img_name) else: img_name = path.basename(img_path) # Get the command for generating the image img_path, tgtcmd_loc = nh.set_img_path(tgtcmd, img_path, cfg) abort_if(img_path=='', 'Unable to parse image path, tgtcmd=' + \ str(tgtcmd) + ', img_name=' + img_name) # Enable persistence for image in the environment env = cfg.get_env(persist=True) if verbose: printv('cmd: %s' % (' '.join(tgtcmd_loc))) printv('env: %s' % (str(env))) printv('stdin: %s' % testcase_f) # Create a tempfile for writing run output fd, tmp = tempfile.mkstemp(prefix='pmfuzz-img-gen-output-') os.close(fd) if verbose: printv('Writing image generation output to ' + tmp) with open(tmp, 'w') as out: with open(testcase_f, 'r') as testcase_obj: exit_code = exec_shell( cmd=tgtcmd_loc, stdin=testcase_obj, stdout=out, stderr=subprocess.STDOUT, env=env, wait=True, timeout = 30 # Set a generous timeout of 30 seconds so things don't crash ) code_desc, success = translate_exit_code(exit_code) if not success: abort('Image generation failed: ' + code_desc) if not path.isfile(img_path): abort('Image generation failed (%s).' % img_path) # Copy the file back to the pmfuzz result directory if compress_img: src = img_path dest = path.join(dest_dir, path.basename(img_path)) dest = nh.get_metadata_files(dest)['pm_cmpr_pool'] compress(src, dest, verbose) remove(src) if verbose: printw('Deleting: ' + src)