From 33d75daf03089cc2fd688632ebe99bc237c4ff19 Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 17 Sep 2022 18:07:42 -0300 Subject: [PATCH 1/6] Save files in local storage as group readable Go creates temporary files as 600 (https://github.com/golang/go/blob/334a591a3f4d868368913328b3e81ddf5b0f46fa/src/os/tempfile.go#L44), but sometimes we want the group to be able to read them (for example, for another user to back up the storage.) --- modules/storage/local.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/storage/local.go b/modules/storage/local.go index 701b0b1a9f3cc..bd380fdc65a72 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -102,6 +102,9 @@ func (l *LocalStorage) Save(path string, r io.Reader, size int64) (int64, error) if err := util.Rename(tmp.Name(), p); err != nil { return 0, err } + if err := os.Chmod(p, 0o640); err != nil { + return 0, err + } tmpRemoved = true From 787485d15952f6b7abe0825490461fc07a7e738c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 24 Sep 2022 20:13:39 +0800 Subject: [PATCH 2/6] apply umask for local storage --- modules/storage/local.go | 3 ++- modules/util/file_unix.go | 28 ++++++++++++++++++++++++++++ modules/util/file_unix_test.go | 32 ++++++++++++++++++++++++++++++++ modules/util/file_windows.go | 12 ++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 modules/util/file_unix.go create mode 100644 modules/util/file_unix_test.go create mode 100644 modules/util/file_windows.go diff --git a/modules/storage/local.go b/modules/storage/local.go index bd380fdc65a72..5d5b06b648d7d 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -102,7 +102,8 @@ func (l *LocalStorage) Save(path string, r io.Reader, size int64) (int64, error) if err := util.Rename(tmp.Name(), p); err != nil { return 0, err } - if err := os.Chmod(p, 0o640); err != nil { + // Golang's tmp file (os.CreateTemp) always have 0o600 mode, so we need to change the file to follow the umask (as what Create/MkDir does) + if err := util.ApplyUmask(p, os.ModePerm); err != nil { return 0, err } diff --git a/modules/util/file_unix.go b/modules/util/file_unix.go new file mode 100644 index 0000000000000..ec9d4ec167a9a --- /dev/null +++ b/modules/util/file_unix.go @@ -0,0 +1,28 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +//go:build !windows + +package util + +import ( + "os" + + "golang.org/x/sys/unix" +) + +var defaultUmask int + +func init() { + // at the moment, the umask could only be gotten by calling unix.Umask(newUmask) + // use 0o077 as temp new umask to reduce the risks if this umask is used anywhere else before the correct umask is recovered + tempUmask := 0o077 + defaultUmask = unix.Umask(tempUmask) + unix.Umask(defaultUmask) +} + +func ApplyUmask(f string, newMode os.FileMode) error { + mod := newMode & ^os.FileMode(defaultUmask) + return os.Chmod(f, mod) +} diff --git a/modules/util/file_unix_test.go b/modules/util/file_unix_test.go new file mode 100644 index 0000000000000..9aa15dc87d0e5 --- /dev/null +++ b/modules/util/file_unix_test.go @@ -0,0 +1,32 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package util + +import ( + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestApplyUmask(t *testing.T) { + f, err := os.CreateTemp(t.TempDir(), "test-filemode-") + assert.NoError(t, err) + + err = os.Chmod(f.Name(), 0777) + assert.NoError(t, err) + st, err := os.Stat(f.Name()) + assert.NoError(t, err) + assert.EqualValues(t, 0o777, st.Mode().Perm()&0o777) + + oldDefaultUmask := defaultUmask + defaultUmask = 0o037 + defer func() { + defaultUmask = oldDefaultUmask + }() + err = ApplyUmask(f.Name(), os.ModePerm) + st, err = os.Stat(f.Name()) + assert.NoError(t, err) + assert.EqualValues(t, 0o740, st.Mode().Perm()&0o777) +} diff --git a/modules/util/file_windows.go b/modules/util/file_windows.go new file mode 100644 index 0000000000000..eeaed41395b46 --- /dev/null +++ b/modules/util/file_windows.go @@ -0,0 +1,12 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +//go:build windows + +package util + +func ApplyUmask(f string) error { + // do nothing for Windows + return nil +} From 77b0036306a3ccac0436e5b353d70ec80ec12807 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 24 Sep 2022 20:16:14 +0800 Subject: [PATCH 3/6] fix windows --- modules/util/file_windows.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/util/file_windows.go b/modules/util/file_windows.go index eeaed41395b46..6f2a1916c609f 100644 --- a/modules/util/file_windows.go +++ b/modules/util/file_windows.go @@ -6,7 +6,7 @@ package util -func ApplyUmask(f string) error { - // do nothing for Windows +func ApplyUmask(f string, newMode os.FileMode) error { + // do nothing for Windows, because Windows doesn't use umask return nil } From c2a47aff6fb0f8c894de1c40d8e94a77ae1ac58c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 24 Sep 2022 20:23:37 +0800 Subject: [PATCH 4/6] fix lint --- modules/util/file_unix_test.go | 3 ++- modules/util/file_windows.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/util/file_unix_test.go b/modules/util/file_unix_test.go index 9aa15dc87d0e5..c2a9a3fddf45d 100644 --- a/modules/util/file_unix_test.go +++ b/modules/util/file_unix_test.go @@ -5,9 +5,10 @@ package util import ( - "github.com/stretchr/testify/assert" "os" "testing" + + "github.com/stretchr/testify/assert" ) func TestApplyUmask(t *testing.T) { diff --git a/modules/util/file_windows.go b/modules/util/file_windows.go index 6f2a1916c609f..6ad3e88ba5eee 100644 --- a/modules/util/file_windows.go +++ b/modules/util/file_windows.go @@ -6,6 +6,10 @@ package util +import ( + "os" +) + func ApplyUmask(f string, newMode os.FileMode) error { // do nothing for Windows, because Windows doesn't use umask return nil From 31fcd9b926438e5be68362ef343bcfe94c5dbbf2 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 24 Sep 2022 20:28:35 +0800 Subject: [PATCH 5/6] fix lint --- modules/util/file_unix_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/util/file_unix_test.go b/modules/util/file_unix_test.go index c2a9a3fddf45d..b590f57f732d2 100644 --- a/modules/util/file_unix_test.go +++ b/modules/util/file_unix_test.go @@ -15,7 +15,7 @@ func TestApplyUmask(t *testing.T) { f, err := os.CreateTemp(t.TempDir(), "test-filemode-") assert.NoError(t, err) - err = os.Chmod(f.Name(), 0777) + err = os.Chmod(f.Name(), 0o777) assert.NoError(t, err) st, err := os.Stat(f.Name()) assert.NoError(t, err) @@ -27,6 +27,7 @@ func TestApplyUmask(t *testing.T) { defaultUmask = oldDefaultUmask }() err = ApplyUmask(f.Name(), os.ModePerm) + assert.NoError(t, err) st, err = os.Stat(f.Name()) assert.NoError(t, err) assert.EqualValues(t, 0o740, st.Mode().Perm()&0o777) From 6f4d6c8ee4384e8f25126ed4f67613c218ae5508 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 24 Sep 2022 20:34:28 +0800 Subject: [PATCH 6/6] fix build --- modules/util/file_unix_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/util/file_unix_test.go b/modules/util/file_unix_test.go index b590f57f732d2..41311aa13f3c9 100644 --- a/modules/util/file_unix_test.go +++ b/modules/util/file_unix_test.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. +//go:build !windows + package util import (