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
This commit is contained in:
+24
-3
@@ -276,6 +276,14 @@ func (m *directManager) rename(old, new string) error {
|
||||
return fmt.Errorf("writing to %q in rename of %q: %w", new, old, err)
|
||||
}
|
||||
|
||||
// Explicitly set the permissions on the new file. This ensures that
|
||||
// if we have a umask set which prevents creating world-readable files,
|
||||
// the file will still have the correct permissions once it's renamed
|
||||
// into place. See #12609.
|
||||
if err := m.fs.Chmod(new, 0644); err != nil {
|
||||
return fmt.Errorf("chmod %q in rename of %q: %w", new, old, err)
|
||||
}
|
||||
|
||||
if err := m.fs.Remove(old); err != nil {
|
||||
err2 := m.fs.Truncate(old)
|
||||
if err2 != nil {
|
||||
@@ -467,6 +475,14 @@ func (m *directManager) atomicWriteFile(fs wholeFileFS, filename string, data []
|
||||
if err := fs.WriteFile(tmpName, data, perm); err != nil {
|
||||
return fmt.Errorf("atomicWriteFile: %w", err)
|
||||
}
|
||||
// Explicitly set the permissions on the temporary file before renaming
|
||||
// it. This ensures that if we have a umask set which prevents creating
|
||||
// world-readable files, the file will still have the correct
|
||||
// permissions once it's renamed into place. See #12609.
|
||||
if err := fs.Chmod(tmpName, perm); err != nil {
|
||||
return fmt.Errorf("atomicWriteFile: Chmod: %w", err)
|
||||
}
|
||||
|
||||
return m.rename(tmpName, filename)
|
||||
}
|
||||
|
||||
@@ -475,10 +491,11 @@ func (m *directManager) atomicWriteFile(fs wholeFileFS, filename string, data []
|
||||
//
|
||||
// All name parameters are absolute paths.
|
||||
type wholeFileFS interface {
|
||||
Stat(name string) (isRegular bool, err error)
|
||||
Rename(oldName, newName string) error
|
||||
Remove(name string) error
|
||||
Chmod(name string, mode os.FileMode) error
|
||||
ReadFile(name string) ([]byte, error)
|
||||
Remove(name string) error
|
||||
Rename(oldName, newName string) error
|
||||
Stat(name string) (isRegular bool, err error)
|
||||
Truncate(name string) error
|
||||
WriteFile(name string, contents []byte, perm os.FileMode) error
|
||||
}
|
||||
@@ -502,6 +519,10 @@ func (fs directFS) Stat(name string) (isRegular bool, err error) {
|
||||
return fi.Mode().IsRegular(), nil
|
||||
}
|
||||
|
||||
func (fs directFS) Chmod(name string, mode os.FileMode) error {
|
||||
return os.Chmod(fs.path(name), mode)
|
||||
}
|
||||
|
||||
func (fs directFS) Rename(oldName, newName string) error {
|
||||
return os.Rename(fs.path(oldName), fs.path(newName))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user