예제 #1
0
파일: state.go 프로젝트: google/syzkaller
func (st *State) addInput(mgr *Manager, input []byte) {
	if _, err := prog.CallSet(input); err != nil {
		Logf(0, "manager %v: failed to extract call set: %v, program:\n%v", mgr.name, err, string(input))
		return
	}
	sig := hash.Hash(input)
	mgr.Corpus[sig] = true
	fname := filepath.Join(mgr.dir, "corpus", sig.String())
	writeFile(fname, nil)
	if st.Corpus[sig] == nil {
		st.Corpus[sig] = &Input{
			seq:  st.seq,
			prog: input,
		}
		fname := filepath.Join(st.dir, "corpus", fmt.Sprintf("%v-%v", sig.String(), st.seq))
		writeFile(fname, input)
	}
}
예제 #2
0
파일: state.go 프로젝트: google/syzkaller
func (st *State) pendingInputs(mgr *Manager) ([][]byte, error) {
	if mgr.seq == st.seq {
		return nil, nil
	}
	var inputs [][]byte
	for sig, inp := range st.Corpus {
		if mgr.seq > inp.seq || mgr.Corpus[sig] {
			continue
		}
		calls, err := prog.CallSet(inp.prog)
		if err != nil {
			return nil, fmt.Errorf("failed to extract call set: %v\nprogram: %v", err, string(inp.prog))
		}
		if !managerSupportsAllCalls(mgr.Calls, calls) {
			continue
		}
		inputs = append(inputs, inp.prog)
	}
	mgr.seq = st.seq
	writeFile(filepath.Join(mgr.dir, "seq"), []byte(fmt.Sprint(mgr.seq)))
	return inputs, nil
}
예제 #3
0
파일: state.go 프로젝트: google/syzkaller
// Make creates State and initializes it from dir.
func Make(dir string) (*State, error) {
	st := &State{
		dir:      dir,
		Corpus:   make(map[hash.Sig]*Input),
		Managers: make(map[string]*Manager),
	}

	corpusDir := filepath.Join(st.dir, "corpus")
	os.MkdirAll(corpusDir, 0700)
	inputs, err := ioutil.ReadDir(corpusDir)
	if err != nil {
		return nil, fmt.Errorf("failed to read %v dir: %v", corpusDir, err)
	}
	for _, inp := range inputs {
		data, err := ioutil.ReadFile(filepath.Join(corpusDir, inp.Name()))
		if err != nil {
			return nil, err
		}
		if _, err := prog.CallSet(data); err != nil {
			return nil, err
		}
		parts := strings.Split(inp.Name(), "-")
		if len(parts) != 2 {
			return nil, fmt.Errorf("bad file in corpus: %v", inp.Name())
		}
		seq, err := strconv.ParseUint(parts[1], 10, 64)
		if err != nil {
			return nil, fmt.Errorf("bad file in corpus: %v", inp.Name())
		}
		sig := hash.Hash(data)
		if sig.String() != parts[0] {
			return nil, fmt.Errorf("bad file in corpus: %v, want hash %v", inp.Name(), sig.String())
		}
		st.Corpus[sig] = &Input{
			seq:  seq,
			prog: data,
		}
		if st.seq < seq {
			st.seq = seq
		}
	}

	managersDir := filepath.Join(st.dir, "manager")
	os.MkdirAll(managersDir, 0700)
	managers, err := ioutil.ReadDir(managersDir)
	if err != nil {
		return nil, fmt.Errorf("failed to read %v dir: %v", managersDir, err)
	}
	for _, manager := range managers {
		mgr := &Manager{
			name: manager.Name(),
		}
		st.Managers[mgr.name] = mgr
		mgr.dir = filepath.Join(managersDir, mgr.name)
		seqStr, _ := ioutil.ReadFile(filepath.Join(mgr.dir, "seq"))
		mgr.seq, _ = strconv.ParseUint(string(seqStr), 10, 64)
		if st.seq < mgr.seq {
			st.seq = mgr.seq
		}

		mgr.Corpus = make(map[hash.Sig]bool)
		corpusDir := filepath.Join(mgr.dir, "corpus")
		os.MkdirAll(corpusDir, 0700)
		corpus, err := ioutil.ReadDir(corpusDir)
		if err != nil {
			return nil, fmt.Errorf("failed to read %v dir: %v", corpusDir, err)
		}
		for _, input := range corpus {
			sig, err := hash.FromString(input.Name())
			if err != nil {
				return nil, fmt.Errorf("bad file in corpus: %v", input.Name())
			}
			mgr.Corpus[sig] = true
		}
	}

	return st, err
}