nuclei icon indicating copy to clipboard operation
nuclei copied to clipboard

Fatal error: concurrent map iteration and map write

Open forgedhallpass opened this issue 3 years ago • 1 comments

Nuclei version: 2.7.3

Steps To Reproduce:

docker run -it -v /root:/root --rm projectdiscovery/nuclei -t /root/test.yaml -l input_urls.txt -stats

test.yaml

id: test

info:
  name: test
  author: tester

requests:
  - method: GET
    path:
      - "{{BaseURL}}/"

This ticket was created based on p1734543's message on Discord.

full_stack_trace.txt input_urls.txt

forgedhallpass avatar Jul 04 '22 10:07 forgedhallpass

Just had a quick look at this and I might be missing something obvious, but this is what I believe is happening /cc @ehsandeep

https://github.com/projectdiscovery/nuclei/blob/dev/v2/pkg/types/resume.go#L25-L39

// ResumeCfg contains the scan progression
type ResumeCfg struct {
	sync.RWMutex
	ResumeFrom map[string]*ResumeInfo `json:"resumeFrom"`
	Current    map[string]*ResumeInfo `json:"-"`
}

type ResumeInfo struct {
	sync.RWMutex
	Completed bool                `json:"completed"`
	InFlight  map[uint32]struct{} `json:"inFlight"`
	SkipUnder uint32              `json:"-"`
	Repeat    map[uint32]struct{} `json:"-"`
	DoAbove   uint32              `json:"-"`
}

Each type has its own mutex. However, when saving the configuration, only one is locked.

https://github.com/projectdiscovery/nuclei/blob/dev/v2/internal/runner/runner.go#L578-L587

// SaveResumeConfig to file
func (r *Runner) SaveResumeConfig(path string) error {
	resumeCfg := types.NewResumeCfg()
	r.resumeCfg.Lock()
	resumeCfg.ResumeFrom = r.resumeCfg.Current
	data, _ := json.MarshalIndent(resumeCfg, "", "\t")
	r.resumeCfg.Unlock()

	return os.WriteFile(path, data, os.ModePerm)
}

Access to ResumeCfg.ResumeFrom should be seiralized via custom ResumeFrom methods. It should be unexported to avoid unserialized accesses to it.

jimen0 avatar Jul 10 '22 11:07 jimen0