Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Goroutine Leak ConnectVerfication() -> Limitter #1250

Open
awerqo opened this issue Oct 21, 2024 · 1 comment
Open

Goroutine Leak ConnectVerfication() -> Limitter #1250

awerqo opened this issue Oct 21, 2024 · 1 comment
Labels
Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors.

Comments

@awerqo
Copy link

awerqo commented Oct 21, 2024

When invoke ConnectVerfication() func in runner it creates new limiter on line 717

func (r *Runner) ConnectVerification() {
r.scanner.ListenHandler.Phase.Set(scan.Scan)
var swg sync.WaitGroup
limiter := ratelimit.New(context.Background(), uint(r.options.Rate), time.Second)

Creating new instances of Limiter starts new goroutine:
https://github.com/projectdiscovery/ratelimit/blob/77dad731f2e9a2e98564787086ade7be2ac33b4e/ratelimit.go#L112-L129

And it closed only if any of two contexts done https://github.com/projectdiscovery/ratelimit/blob/main/ratelimit.go#L39-L45

select {
case <-ctx.Done():
	// Internal Context
	imiter.ticker.Stop()
	eturn
case <-limiter.ctx.Done():
	limiter.ticker.Stop()
	return
case ...

So this happens if original context done or if we call stop method https://github.com/projectdiscovery/ratelimit/blob/77dad731f2e9a2e98564787086ade7be2ac33b4e/ratelimit.go#L101-L106 that cancel second, created context https://github.com/projectdiscovery/ratelimit/blob/77dad731f2e9a2e98564787086ade7be2ac33b4e/ratelimit.go#L113

As we can see, when we invoke ConnectVerification() it creates new instance of limiter with context.Background() and not invoke Stop() later:

limiter := ratelimit.New(context.Background(), uint(r.options.Rate), time.Second)
verifiedResult := result.NewResult()
for hostResult := range r.scanner.ScanResults.GetIPsPorts() {
limiter.Take()
swg.Add(1)
go func(hostResult *result.HostResult) {
defer swg.Done()
results := r.scanner.ConnectVerify(hostResult.IP, hostResult.Ports)
verifiedResult.SetPorts(hostResult.IP, results)
}(hostResult)
}
r.scanner.ScanResults = verifiedResult
swg.Wait()

So, we leak goroutine every ConnectVerification() call, what sometimes creates problems if we work with naabu in SDK mode

Thanks

@awerqo awerqo added the Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors. label Oct 21, 2024
@awerqo
Copy link
Author

awerqo commented Oct 21, 2024

I can send a pr if it is convenient for you. It looks like it is safe to call limiter.Stop() after waiting for the swg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors.
Projects
None yet
Development

No branches or pull requests

1 participant