core: Use port ranges to avoid OOM with bad inputs (#2859)

* fix OOM issue caught by fuzzing

* use ParsedAddress as the struct name for the result of ParseNetworkAddress

* simplify code using the ParsedAddress type

* minor cleanups
This commit is contained in:
Mohammed Al Sahaf
2019-11-12 01:33:38 +03:00
committed by Matt Holt
parent a19da07b72
commit 93bc1b72e3
8 changed files with 201 additions and 130 deletions

View File

@ -16,8 +16,7 @@ package reverseproxy
import (
"fmt"
"net"
"strings"
"strconv"
"sync/atomic"
"github.com/caddyserver/caddy/v2"
@ -193,27 +192,20 @@ func (di DialInfo) String() string {
// the given Replacer. Note that the returned value is not a pointer.
func fillDialInfo(upstream *Upstream, repl caddy.Replacer) (DialInfo, error) {
dial := repl.ReplaceAll(upstream.Dial, "")
netw, addrs, err := caddy.ParseNetworkAddress(dial)
addr, err := caddy.ParseNetworkAddress(dial)
if err != nil {
return DialInfo{}, fmt.Errorf("upstream %s: invalid dial address %s: %v", upstream.Dial, dial, err)
}
if len(addrs) != 1 {
if numPorts := addr.PortRangeSize(); numPorts != 1 {
return DialInfo{}, fmt.Errorf("upstream %s: dial address must represent precisely one socket: %s represents %d",
upstream.Dial, dial, len(addrs))
}
var dialHost, dialPort string
if !strings.Contains(netw, "unix") {
dialHost, dialPort, err = net.SplitHostPort(addrs[0])
if err != nil {
dialHost = addrs[0] // assume there was no port
}
upstream.Dial, dial, numPorts)
}
return DialInfo{
Upstream: upstream,
Network: netw,
Address: addrs[0],
Host: dialHost,
Port: dialPort,
Network: addr.Network,
Address: addr.JoinHostPort(0),
Host: addr.Host,
Port: strconv.Itoa(int(addr.StartPort)),
}, nil
}