diff --git a/daemon/libnetwork/internal/resolvconf/resolvconf.go b/daemon/libnetwork/internal/resolvconf/resolvconf.go index 1df28ae0f2..6c8b2523c4 100644 --- a/daemon/libnetwork/internal/resolvconf/resolvconf.go +++ b/daemon/libnetwork/internal/resolvconf/resolvconf.go @@ -18,6 +18,7 @@ import ( "bufio" "bytes" "context" + "fmt" "io" "io/fs" "net/netip" @@ -115,7 +116,15 @@ func Parse(reader io.Reader, path string) (ResolvConf, error) { rc.processLine(scanner.Text()) } if err := scanner.Err(); err != nil { - return ResolvConf{}, systemError{err} + src := rc.md.SourcePath + if errors.Is(err, bufio.ErrTooLong) { + return ResolvConf{}, systemError{ + fmt.Errorf("failed to parse resolv.conf from %s: line too long (exceeds %d)", src, bufio.MaxScanTokenSize), + } + } + return ResolvConf{}, systemError{ + fmt.Errorf("failed to parse resolv.conf from %s: %w", src, err), + } } if _, ok := rc.Option("ndots"); ok { rc.md.NDotsFrom = "host" diff --git a/daemon/libnetwork/internal/resolvconf/resolvconf_test.go b/daemon/libnetwork/internal/resolvconf/resolvconf_test.go index e1079653e4..8996e321c9 100644 --- a/daemon/libnetwork/internal/resolvconf/resolvconf_test.go +++ b/daemon/libnetwork/internal/resolvconf/resolvconf_test.go @@ -1,6 +1,7 @@ package resolvconf import ( + "bufio" "bytes" "io/fs" "net/netip" @@ -553,6 +554,16 @@ unrecognised thing assert.Check(t, golden.String(string(content), t.Name()+".golden")) } +// TestRCParseErrors tests that attempting to read a resolv.conf with a +// very long line produces a useful error. +// see https://github.com/moby/moby/issues/51679#issuecomment-3714403300 +func TestRCParseErrors(t *testing.T) { + input := strings.Repeat("a", bufio.MaxScanTokenSize+1) + "\n" + + _, err := Parse(bytes.NewBufferString(input), "/etc/resolv.conf") + assert.Error(t, err, `failed to parse resolv.conf from /etc/resolv.conf: line too long (exceeds 65536)`) +} + func BenchmarkGenerate(b *testing.B) { rc := &ResolvConf{ nameServers: []netip.Addr{