From 201ef10de6d2241ee21b0bb2b2908af2c3c56a83 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Thu, 23 Dec 2021 20:16:08 +0300 Subject: [PATCH] Pull request: 3987 Fix nil pointer dereference Merge in DNS/adguard-home from 3987-fix-nil-deref to master Updates #3987. Updates #2846. Squashed commit of the following: commit d653e09ce88a8b10b2a17fea1563c419895c714c Author: Eugene Burkov Date: Thu Dec 23 20:08:51 2021 +0300 all: log changes commit c47a4eeacf76fa7df2d01af166dee9d52528ac58 Author: Eugene Burkov Date: Thu Dec 23 19:22:39 2021 +0300 aghnet: fix windows tests commit 9c91f14ccfe967ada3c00ddb86d673238e52c12d Author: Eugene Burkov Date: Thu Dec 23 19:09:49 2021 +0300 aghnet: imp code readability, docs commit d3df15d1892e4ebfe7f8ea7144e39a0c712fce52 Author: Eugene Burkov Date: Thu Dec 23 18:47:28 2021 +0300 aghnet: fix nil pointer dereference --- CHANGELOG.md | 5 +++++ internal/aghnet/net.go | 9 +++++++-- internal/aghnet/net_test.go | 19 +++++++++++++++++++ internal/aghnet/net_unix.go | 1 + internal/aghnet/net_windows.go | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 827f4bf2..a8e5888a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,11 +27,16 @@ and this project adheres to --> - Go 1.17 support. v0.109.0 will require at least Go 1.18 to build. +### Fixed + +- Panic on port availability check during installation ([#3987]). + ### Removed - Go 1.16 support. [#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057 +[#3987]: https://github.com/AdguardTeam/AdGuardHome/issues/3987 diff --git a/internal/aghnet/net.go b/internal/aghnet/net.go index f8e36406..77bdcc63 100644 --- a/internal/aghnet/net.go +++ b/internal/aghnet/net.go @@ -187,7 +187,8 @@ func GetSubnet(ifaceName string) *net.IPNet { return nil } -// CheckPort checks if the port is available for binding. +// CheckPort checks if the port is available for binding. network is expected +// to be one of "udp" and "tcp". func CheckPort(network string, ip net.IP, port int) (err error) { var c io.Closer addr := netutil.IPPort{IP: ip, Port: port}.String() @@ -200,7 +201,11 @@ func CheckPort(network string, ip net.IP, port int) (err error) { return nil } - return errors.WithDeferred(err, closePortChecker(c)) + if err != nil { + return err + } + + return closePortChecker(c) } // IsAddrInUse checks if err is about unsuccessful address binding. diff --git a/internal/aghnet/net_test.go b/internal/aghnet/net_test.go index 38fdf9cc..2e3f54be 100644 --- a/internal/aghnet/net_test.go +++ b/internal/aghnet/net_test.go @@ -5,6 +5,8 @@ import ( "testing" "github.com/AdguardTeam/AdGuardHome/internal/aghtest" + "github.com/AdguardTeam/golibs/netutil" + "github.com/AdguardTeam/golibs/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -69,3 +71,20 @@ func TestBroadcastFromIPNet(t *testing.T) { }) } } + +func TestCheckPort(t *testing.T) { + l, err := net.Listen("tcp", "127.0.0.1:") + require.NoError(t, err) + testutil.CleanupAndRequireSuccess(t, l.Close) + + ipp := netutil.IPPortFromAddr(l.Addr()) + require.NotNil(t, ipp) + require.NotNil(t, ipp.IP) + require.NotZero(t, ipp.Port) + + err = CheckPort("tcp", ipp.IP, ipp.Port) + target := &net.OpError{} + require.ErrorAs(t, err, &target) + + assert.Equal(t, "listen", target.Op) +} diff --git a/internal/aghnet/net_unix.go b/internal/aghnet/net_unix.go index 9f0f5011..27b79579 100644 --- a/internal/aghnet/net_unix.go +++ b/internal/aghnet/net_unix.go @@ -10,6 +10,7 @@ import ( "github.com/AdguardTeam/golibs/errors" ) +// closePortChecker closes c. c must be non-nil. func closePortChecker(c io.Closer) (err error) { return c.Close() } diff --git a/internal/aghnet/net_windows.go b/internal/aghnet/net_windows.go index bbbb81d7..128f5716 100644 --- a/internal/aghnet/net_windows.go +++ b/internal/aghnet/net_windows.go @@ -25,6 +25,7 @@ func ifaceSetStaticIP(string) (err error) { return aghos.Unsupported("setting static ip") } +// closePortChecker closes c. c must be non-nil. func closePortChecker(c io.Closer) (err error) { if err = c.Close(); err != nil { return err