Skip to content

Commit

Permalink
fix: resolve overflow security issue and use wrapped error
Browse files Browse the repository at this point in the history
  • Loading branch information
ksw2000 committed Dec 20, 2024
1 parent 7df609c commit d915e9d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
4 changes: 2 additions & 2 deletions tcplisten/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ func newSocketCloexecOld(domain, typ, proto int) (int, error) {
}
syscall.ForkLock.RUnlock()
if err != nil {
return -1, fmt.Errorf("cannot create listening socket: %s", err)
return -1, fmt.Errorf("cannot create listening socket: %w", err)
}
if err = syscall.SetNonblock(fd, true); err != nil {
syscall.Close(fd)
return -1, fmt.Errorf("cannot make non-blocked listening socket: %s", err)
return -1, fmt.Errorf("cannot make non-blocked listening socket: %w", err)
}
return fd, nil
}
2 changes: 1 addition & 1 deletion tcplisten/socket_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ func newSocketCloexec(domain, typ, proto int) (int, error) {
return newSocketCloexecOld(domain, typ, proto)
}

return -1, fmt.Errorf("cannot create listening unblocked socket: %s", err)
return -1, fmt.Errorf("cannot create listening unblocked socket: %w", err)
}
35 changes: 26 additions & 9 deletions tcplisten/tcplisten.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package tcplisten
import (
"errors"
"fmt"
"math"
"net"
"os"
"syscall"
Expand Down Expand Up @@ -84,18 +85,18 @@ func (cfg *Config) fdSetup(fd int, sa syscall.Sockaddr, addr string) error {
var err error

if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
return fmt.Errorf("cannot enable SO_REUSEADDR: %s", err)
return fmt.Errorf("cannot enable SO_REUSEADDR: %w", err)
}

// This should disable Nagle's algorithm in all accepted sockets by default.
// Users may enable it with net.TCPConn.SetNoDelay(false).
if err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1); err != nil {
return fmt.Errorf("cannot disable Nagle's algorithm: %s", err)
return fmt.Errorf("cannot disable Nagle's algorithm: %w", err)
}

if cfg.ReusePort {
if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
return fmt.Errorf("cannot enable SO_REUSEPORT: %s", err)
return fmt.Errorf("cannot enable SO_REUSEPORT: %w", err)
}
}

Expand All @@ -112,17 +113,17 @@ func (cfg *Config) fdSetup(fd int, sa syscall.Sockaddr, addr string) error {
}

if err = syscall.Bind(fd, sa); err != nil {
return fmt.Errorf("cannot bind to %q: %s", addr, err)
return fmt.Errorf("cannot bind to %q: %w", addr, err)
}

backlog := cfg.Backlog
if backlog <= 0 {
if backlog, err = soMaxConn(); err != nil {
return fmt.Errorf("cannot determine backlog to pass to listen(2): %s", err)
return fmt.Errorf("cannot determine backlog to pass to listen(2): %w", err)
}
}
if err = syscall.Listen(fd, backlog); err != nil {
return fmt.Errorf("cannot listen on %q: %s", addr, err)
return fmt.Errorf("cannot listen on %q: %w", addr, err)
}

return nil
Expand All @@ -149,7 +150,10 @@ func getSockaddr(network, addr string) (sa syscall.Sockaddr, soType int, err err
if err != nil {
return nil, -1, err
}
sa6.ZoneId = uint32(ifi.Index)
sa6.ZoneId, err = safeIntToUint32(ifi.Index)
if err != nil {
return nil, -1, fmt.Errorf("unexpected convert net interface index int to uint32: %w", err)
}
}
return &sa6, syscall.AF_INET6, nil
case "tcp":
Expand All @@ -164,10 +168,23 @@ func getSockaddr(network, addr string) (sa syscall.Sockaddr, soType int, err err
if err != nil {
return nil, -1, err
}
sa6.ZoneId = uint32(ifi.Index)
sa6.ZoneId, err = safeIntToUint32(ifi.Index)
if err != nil {
return nil, -1, fmt.Errorf("unexpected convert net interface index int to uint32: %w", err)
}
}
return &sa6, syscall.AF_INET6, nil
default:
return nil, -1, errors.New("only tcp, tcp4, or tcp6 is supported: " + network)
return nil, -1, errors.New("only tcp, tcp4, or tcp6 is supported " + network)
}
}

func safeIntToUint32(i int) (uint32, error) {
if i < 0 {
return 0, errors.New("value is negative, cannot convert to uint32")
}
if i > math.MaxUint32 {
return 0, errors.New("value exceeds uint32 max value")
}
return uint32(i), nil
}

0 comments on commit d915e9d

Please sign in to comment.