Skip to content

Data race in Proxy.pipeRemote() #341

@andres-portainer

Description

@andres-portainer

There is a data race in this line https://github.com/jpillora/chisel/blob/master/share/tunnel/tunnel_in_proxy.go#L125.

Here is a simple example that shows the problem:

package main

import (
	"context"
	"log"
	"net/http"
	"time"

	chclient "github.com/jpillora/chisel/client"
	chserver "github.com/jpillora/chisel/server"
)

func main() {
	// Server
	srv, err := chserver.NewServer(&chserver.Config{
		Reverse: true,
	})
	if err != nil {
		log.Fatal(err)
	}

	if err := srv.Start("127.0.0.1", "55555"); err != nil {
		log.Fatal(err)
	}

	// Client
	cli, err := chclient.NewClient(&chclient.Config{
		Server:  "localhost:55555",
		Remotes: []string{"R:127.0.0.1:44444:33333"},
	})
	if err != nil {
		log.Fatal(err)
	}

	cli.Start(context.Background())

	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Second)
		http.Get("http://127.0.0.1:44444/")
	}
}

Which gives the following output while running it with the race detector enabled:

==================
WARNING: DATA RACE
Read at 0x00c00013f6a0 by goroutine 46:
  github.com/jpillora/chisel/share/tunnel.(*Proxy).pipeRemote()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:125 +0xf6
  github.com/jpillora/chisel/share/tunnel.(*Proxy).runTCP·dwrap·5()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:119 +0x71

Previous write at 0x00c00013f6a0 by goroutine 35:
  github.com/jpillora/chisel/share/tunnel.(*Proxy).pipeRemote()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:125 +0x114
  github.com/jpillora/chisel/share/tunnel.(*Proxy).runTCP·dwrap·5()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:119 +0x71

Goroutine 46 (running) created at:
  github.com/jpillora/chisel/share/tunnel.(*Proxy).runTCP()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:119 +0x165
  github.com/jpillora/chisel/share/tunnel.(*Proxy).Run()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:76 +0x2fb
  github.com/jpillora/chisel/share/tunnel.(*Tunnel).BindRemotes.func1()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel.go:166 +0x4f
  golang.org/x/sync/errgroup.(*Group).Go.func1()
      /home/user/gopath/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x96

Goroutine 35 (finished) created at:
  github.com/jpillora/chisel/share/tunnel.(*Proxy).runTCP()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:119 +0x165
  github.com/jpillora/chisel/share/tunnel.(*Proxy).Run()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel_in_proxy.go:76 +0x2fb
  github.com/jpillora/chisel/share/tunnel.(*Tunnel).BindRemotes.func1()
      /home/user/gopath/pkg/mod/github.com/jpillora/[email protected]/share/tunnel/tunnel.go:166 +0x4f
  golang.org/x/sync/errgroup.(*Group).Go.func1()
      /home/user/gopath/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x96
==================
Found 1 data race(s)

The possible solutions include:

  1. Using sync/atomic to increment/read p.count
  2. Using a sync.Mutex or sync.RWMutex to lock before using p.count
  3. Having a counting goroutine in background that supplies increasing numbers through a channel

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions