aboutsummaryrefslogtreecommitdiff
path: root/filesystem
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2021-12-19 21:19:25 -0600
committerEric Biggers <ebiggers@google.com>2021-12-19 21:44:59 -0600
commit4c7c6631cc5a27cc6b4431f5ad3805a2d624c5f5 (patch)
treeb22856e0d3392a2def633d961ad29c2890ce4fb2 /filesystem
parent360467d0df626d2d0eac003a0a210814910804ce (diff)
Set owner of login protectors to correct user
When the root user creates a login protector for a non-root user, make sure to chown() the protector file to make it owned by the user. Without this, the protector cannot be updated by the user, which causes it to get out of sync if the user changes their login passphrase. Fixes https://github.com/google/fscrypt/issues/319
Diffstat (limited to 'filesystem')
-rw-r--r--filesystem/filesystem.go33
1 files changed, 26 insertions, 7 deletions
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 9b5b7e2..456a4fc 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -37,6 +37,7 @@ import (
"io/ioutil"
"log"
"os"
+ "os/user"
"path/filepath"
"sort"
"strings"
@@ -47,6 +48,7 @@ import (
"golang.org/x/sys/unix"
"github.com/google/fscrypt/metadata"
+ "github.com/google/fscrypt/util"
)
// ErrAlreadySetup indicates that a filesystem is already setup for fscrypt.
@@ -392,7 +394,7 @@ func syncDirectory(dirPath string) error {
// writeDataAtomic writes the data to the path such that the data is either
// written to stable storage or an error is returned.
-func (m *Mount) writeDataAtomic(path string, data []byte) error {
+func (m *Mount) writeDataAtomic(path string, data []byte, owner *user.User) error {
// Write the data to a temporary file, sync it, then rename into place
// so that the operation will be atomic.
dirPath := filepath.Dir(path)
@@ -407,6 +409,14 @@ func (m *Mount) writeDataAtomic(path string, data []byte) error {
tempFile.Close()
return err
}
+ if owner != nil {
+ if err = util.Chown(tempFile, owner); err != nil {
+ log.Printf("could not set owner of %q to %v: %v",
+ path, owner.Username, err)
+ tempFile.Close()
+ return err
+ }
+ }
if _, err = tempFile.Write(data); err != nil {
tempFile.Close()
return err
@@ -428,7 +438,7 @@ func (m *Mount) writeDataAtomic(path string, data []byte) error {
// addMetadata writes the metadata structure to the file with the specified
// path. This will overwrite any existing data. The operation is atomic.
-func (m *Mount) addMetadata(path string, md metadata.Metadata) error {
+func (m *Mount) addMetadata(path string, md metadata.Metadata, owner *user.User) error {
if err := md.CheckValidity(); err != nil {
return errors.Wrap(err, "provided metadata is invalid")
}
@@ -439,7 +449,7 @@ func (m *Mount) addMetadata(path string, md metadata.Metadata) error {
}
log.Printf("writing metadata to %q", path)
- return m.writeDataAtomic(path, data)
+ return m.writeDataAtomic(path, data, owner)
}
// getMetadata reads the metadata structure from the file with the specified
@@ -480,7 +490,8 @@ func (m *Mount) removeMetadata(path string) error {
// will fail with ErrLinkedProtector if a linked protector with this descriptor
// already exists on the filesystem.
func (m *Mount) AddProtector(data *metadata.ProtectorData) error {
- if err := m.CheckSetup(); err != nil {
+ var err error
+ if err = m.CheckSetup(); err != nil {
return err
}
if isRegularFile(m.linkedProtectorPath(data.ProtectorDescriptor)) {
@@ -488,7 +499,15 @@ func (m *Mount) AddProtector(data *metadata.ProtectorData) error {
data.ProtectorDescriptor, m.Path)
}
path := m.protectorPath(data.ProtectorDescriptor)
- return m.addMetadata(path, data)
+
+ var owner *user.User
+ if data.Source == metadata.SourceType_pam_passphrase && util.IsUserRoot() {
+ owner, err = util.UserFromUID(data.Uid)
+ if err != nil {
+ return err
+ }
+ }
+ return m.addMetadata(path, data, owner)
}
// AddLinkedProtector adds a link in this filesystem to the protector metadata
@@ -528,7 +547,7 @@ func (m *Mount) AddLinkedProtector(descriptor string, dest *Mount) (bool, error)
if err != nil {
return false, err
}
- return true, m.writeDataAtomic(linkPath, []byte(newLink))
+ return true, m.writeDataAtomic(linkPath, []byte(newLink), nil)
}
// GetRegularProtector looks up the protector metadata by descriptor. This will
@@ -609,7 +628,7 @@ func (m *Mount) AddPolicy(data *metadata.PolicyData) error {
return err
}
- return m.addMetadata(m.PolicyPath(data.KeyDescriptor), data)
+ return m.addMetadata(m.PolicyPath(data.KeyDescriptor), data, nil)
}
// GetPolicy looks up the policy metadata by descriptor.