From 21e9f98fc12d767c2408195da19d9893f9de9224 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 24 Sep 2021 15:24:16 -0600 Subject: [PATCH] ipn, paths: unconditionally attempt to set state dir perms, but only if the state dir is ours We unconditionally set appropriate perms on the statefile dir. We look at the basename of the statefile dir, and if it is "tailscale", then we set perms as appropriate. Fixes #2925 Updates #2856 Signed-off-by: Aaron Klotz --- ipn/store.go | 8 +++++--- paths/paths_unix.go | 10 +++++----- paths/paths_windows.go | 5 +++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ipn/store.go b/ipn/store.go index c4f0d2c6d..1bf8194de 100644 --- a/ipn/store.go +++ b/ipn/store.go @@ -170,6 +170,11 @@ func (s *FileStore) String() string { return fmt.Sprintf("FileStore(%q)", s.path // NewFileStore returns a new file store that persists to path. func NewFileStore(path string) (*FileStore, error) { + // We unconditionally call this to ensure that our perms are correct + if err := paths.MkStateDir(filepath.Dir(path)); err != nil { + return nil, fmt.Errorf("creating state directory: %w", err) + } + bs, err := ioutil.ReadFile(path) // Treat an empty file as a missing file. @@ -183,9 +188,6 @@ func NewFileStore(path string) (*FileStore, error) { if os.IsNotExist(err) { // Write out an initial file, to verify that we can write // to the path. - if err := paths.MkStateDir(filepath.Dir(path)); err != nil { - return nil, fmt.Errorf("creating state directory: %w", err) - } if err = atomicfile.WriteFile(path, []byte("{}"), 0600); err != nil { return nil, err } diff --git a/paths/paths_unix.go b/paths/paths_unix.go index 0bc413ad1..17662b0f8 100644 --- a/paths/paths_unix.go +++ b/paths/paths_unix.go @@ -63,9 +63,9 @@ func xdgDataHome() string { } func ensureStateDirPerms(dirPath string) error { - // Unfortunately there are currently numerous tests that set up state files - // right off of /tmp, on which Chmod will of course fail. We should fix our - // test harnesses to not do that, at which point we can return an error. - os.Chmod(dirPath, 0700) - return nil + if filepath.Base(dirPath) != "tailscale" { + return nil + } + + return os.Chmod(dirPath, 0700) } diff --git a/paths/paths_windows.go b/paths/paths_windows.go index 75d49100a..e00a8062a 100644 --- a/paths/paths_windows.go +++ b/paths/paths_windows.go @@ -6,6 +6,8 @@ package paths import ( "os" + "path/filepath" + "strings" "unsafe" "golang.org/x/sys/windows" @@ -86,6 +88,9 @@ func ensureStateDirPerms(dirPath string) error { if !fi.IsDir() { return os.ErrInvalid } + if strings.ToLower(filepath.Base(dirPath)) != "tailscale" { + return nil + } // We need the info for our current user as SIDs sids, err := getCurrentUserSids()