tailscale/net/dns/direct_unix_test.go
Andrew Dunham 53a5d00fff net/dns: ensure /etc/resolv.conf is world-readable even with a umask
Previously, if we had a umask set (e.g. 0027) that prevented creating a
world-readable file, /etc/resolv.conf would be created without the o+r
bit and thus other users may be unable to resolve DNS.

Since a umask only applies to file creation, chmod the file after
creation and before renaming it to ensure that it has the appropriate
permissions.

Updates #12609

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I2a05d64f4f3a8ee8683a70be17a7da0e70933137
2024-06-26 00:02:05 -04:00

44 lines
969 B
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build unix
package dns
import (
"context"
"os"
"path/filepath"
"syscall"
"testing"
)
func TestWriteFileUmask(t *testing.T) {
// Set a umask that disallows world-readable files for the duration of
// this test.
oldUmask := syscall.Umask(0027)
defer syscall.Umask(oldUmask)
tmp := t.TempDir()
fs := directFS{prefix: tmp}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
m := directManager{logf: t.Logf, fs: fs, ctx: ctx, ctxClose: cancel}
const perms = 0644
if err := m.atomicWriteFile(fs, "resolv.conf", []byte("nameserver 8.8.8.8\n"), perms); err != nil {
t.Fatal(err)
}
// Ensure that the created file has the world-readable bit set.
fi, err := os.Stat(filepath.Join(tmp, "resolv.conf"))
if err != nil {
t.Fatal(err)
}
if got := fi.Mode().Perm(); got != perms {
t.Fatalf("file mode: got 0o%o, want 0o%o", got, perms)
}
}