summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/caddyhttp.go
diff options
context:
space:
mode:
authorMohammed Al Sahaf <msaa1990@gmail.com>2019-11-12 01:33:38 +0300
committerMatt Holt <mholt@users.noreply.github.com>2019-11-11 15:33:38 -0700
commit93bc1b72e3cd566e6447ad7a1f832474aad5dfcc (patch)
tree05ddeb324261d7058925948baa0077752fd5e453 /modules/caddyhttp/caddyhttp.go
parenta19da07b72d84432341990bcedce511fe2f980da (diff)
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
Diffstat (limited to 'modules/caddyhttp/caddyhttp.go')
-rw-r--r--modules/caddyhttp/caddyhttp.go33
1 files changed, 18 insertions, 15 deletions
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go
index 99a64c3..36d8154 100644
--- a/modules/caddyhttp/caddyhttp.go
+++ b/modules/caddyhttp/caddyhttp.go
@@ -135,15 +135,18 @@ func (app *App) Validate() error {
lnAddrs := make(map[string]string)
for srvName, srv := range app.Servers {
for _, addr := range srv.Listen {
- netw, expanded, err := caddy.ParseNetworkAddress(addr)
+ listenAddr, err := caddy.ParseNetworkAddress(addr)
if err != nil {
return fmt.Errorf("invalid listener address '%s': %v", addr, err)
}
- for _, a := range expanded {
- if sn, ok := lnAddrs[netw+a]; ok {
- return fmt.Errorf("server %s: listener address repeated: %s (already claimed by server '%s')", srvName, a, sn)
+ // check that every address in the port range is unique to this server;
+ // we do not use <= here because PortRangeSize() adds 1 to EndPort for us
+ for i := uint(0); i < listenAddr.PortRangeSize(); i++ {
+ addr := caddy.JoinNetworkAddress(listenAddr.Network, listenAddr.Host, strconv.Itoa(int(listenAddr.StartPort+i)))
+ if sn, ok := lnAddrs[addr]; ok {
+ return fmt.Errorf("server %s: listener address repeated: %s (already claimed by server '%s')", srvName, addr, sn)
}
- lnAddrs[netw+a] = srvName
+ lnAddrs[addr] = srvName
}
}
}
@@ -176,14 +179,15 @@ func (app *App) Start() error {
}
for _, lnAddr := range srv.Listen {
- network, addrs, err := caddy.ParseNetworkAddress(lnAddr)
+ listenAddr, err := caddy.ParseNetworkAddress(lnAddr)
if err != nil {
return fmt.Errorf("%s: parsing listen address '%s': %v", srvName, lnAddr, err)
}
- for _, addr := range addrs {
- ln, err := caddy.Listen(network, addr)
+ for i := uint(0); i <= listenAddr.PortRangeSize(); i++ {
+ hostport := listenAddr.JoinHostPort(i)
+ ln, err := caddy.Listen(listenAddr.Network, hostport)
if err != nil {
- return fmt.Errorf("%s: listening on %s: %v", network, addr, err)
+ return fmt.Errorf("%s: listening on %s: %v", listenAddr.Network, hostport, err)
}
// enable HTTP/2 by default
@@ -194,11 +198,10 @@ func (app *App) Start() error {
}
// enable TLS
- _, port, _ := net.SplitHostPort(addr)
- if len(srv.TLSConnPolicies) > 0 && port != strconv.Itoa(app.httpPort()) {
+ if len(srv.TLSConnPolicies) > 0 && int(i) != app.httpPort() {
tlsCfg, err := srv.TLSConnPolicies.TLSConfig(app.ctx)
if err != nil {
- return fmt.Errorf("%s/%s: making TLS configuration: %v", network, addr, err)
+ return fmt.Errorf("%s/%s: making TLS configuration: %v", listenAddr.Network, hostport, err)
}
ln = tls.NewListener(ln, tlsCfg)
@@ -206,15 +209,15 @@ func (app *App) Start() error {
// TODO: HTTP/3 support is experimental for now
if srv.ExperimentalHTTP3 {
app.logger.Info("enabling experimental HTTP/3 listener",
- zap.String("addr", addr),
+ zap.String("addr", hostport),
)
- h3ln, err := caddy.ListenPacket("udp", addr)
+ h3ln, err := caddy.ListenPacket("udp", hostport)
if err != nil {
return fmt.Errorf("getting HTTP/3 UDP listener: %v", err)
}
h3srv := &http3.Server{
Server: &http.Server{
- Addr: addr,
+ Addr: hostport,
Handler: srv,
TLSConfig: tlsCfg,
},