diff options
| author | Eric Biggers <ebiggers@google.com> | 2019-12-15 19:31:39 -0800 |
|---|---|---|
| committer | Eric Biggers <ebiggers@google.com> | 2020-01-05 10:02:13 -0800 |
| commit | 42e0dfe85ec7a75a2fa30c417d57eae60b5a881d (patch) | |
| tree | ffa9fb08a5bbe51ec23bf219ef206ddc81799453 /keyring/keyring.go | |
| parent | 2b25de6d445faefc28629603dd754aec9f744e60 (diff) | |
Keyring support for v2 encryption policies
Implement adding/removing v2 encryption policy keys to/from the kernel.
The kernel requires that the new ioctls FS_IOC_ADD_ENCRYPTION_KEY and
FS_IOC_REMOVE_ENCRYPTION_KEY be used for this. Root is not required.
However, non-root support brings an extra complication: the kernel keeps
track of which users have called FS_IOC_ADD_ENCRYPTION_KEY for the same
key. FS_IOC_REMOVE_ENCRYPTION_KEY only works as one of these users, and
it only removes the calling user's claim to the key; the key is only
truly removed when the last claim is removed.
Implement the following behavior:
- 'fscrypt unlock' and pam_fscrypt add the key for the user, even if
other user(s) have it added already. This behavior is needed so that
another user can't remove the key out from under the user.
- 'fscrypt lock' and pam_fscrypt remove the key for the user. However,
if the key wasn't truly removed because other users still have it
added, 'fscrypt lock' prints a warning.
- 'fscrypt status' shows whether the directory is unlocked for anyone.
Diffstat (limited to 'keyring/keyring.go')
| -rw-r--r-- | keyring/keyring.go | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/keyring/keyring.go b/keyring/keyring.go index f0bd1b7..925d059 100644 --- a/keyring/keyring.go +++ b/keyring/keyring.go @@ -22,15 +22,18 @@ // keyring.go, and they delegate to either user_keyring.go or fs_keyring.go, // depending on whether a user keyring or a filesystem keyring is being used. // +// v2 encryption policies always use the filesystem keyring. // v1 policies use the user keyring by default, but can be configured to use the // filesystem keyring instead (requires root and kernel v5.4+). package keyring import ( + "encoding/hex" "os/user" "strconv" "github.com/pkg/errors" + "golang.org/x/sys/unix" "github.com/google/fscrypt/crypto" "github.com/google/fscrypt/filesystem" @@ -40,14 +43,15 @@ import ( // Keyring error values var ( - ErrKeyAdd = util.SystemError("could not add key to the keyring") - ErrKeyRemove = util.SystemError("could not remove key from the keyring") - ErrKeyNotPresent = errors.New("key not present or already removed") - ErrKeyFilesOpen = errors.New("some files using the key are still open") - ErrKeySearch = errors.New("could not find key with descriptor") - ErrSessionUserKeying = errors.New("user keyring not linked into session keyring") - ErrAccessUserKeyring = errors.New("could not access user keyring") - ErrLinkUserKeyring = util.SystemError("could not link user keyring into root keyring") + ErrKeyAdd = util.SystemError("could not add key to the keyring") + ErrKeyRemove = util.SystemError("could not remove key from the keyring") + ErrKeyNotPresent = errors.New("key not present or already removed") + ErrKeyFilesOpen = errors.New("some files using the key are still open") + ErrKeyAddedByOtherUsers = errors.New("other users have added the key too") + ErrKeySearch = errors.New("could not find key with descriptor") + ErrSessionUserKeying = errors.New("user keyring not linked into session keyring") + ErrAccessUserKeyring = errors.New("could not access user keyring") + ErrLinkUserKeyring = util.SystemError("could not link user keyring into root keyring") ) // Options are the options which specify *which* keyring the key should be @@ -69,9 +73,15 @@ type Options struct { } func shouldUseFsKeyring(descriptor string, options *Options) bool { - // Use the filesystem keyring if use_fs_keyring_for_v1_policies is set - // in /etc/fscrypt.conf and the kernel supports it. - return options.UseFsKeyringForV1Policies && isFsKeyringSupported(options.Mount) + // For v1 encryption policy keys, use the filesystem keyring if + // use_fs_keyring_for_v1_policies is set in /etc/fscrypt.conf and the + // kernel supports it. + if len(descriptor) == hex.EncodedLen(unix.FSCRYPT_KEY_DESCRIPTOR_SIZE) { + return options.UseFsKeyringForV1Policies && isFsKeyringSupported(options.Mount) + } + // For v2 encryption policy keys, always use the filesystem keyring; the + // kernel doesn't support any other way. + return true } // AddEncryptionKey adds an encryption policy key to a kernel keyring. It uses @@ -106,6 +116,7 @@ const ( KeyAbsent KeyAbsentButFilesBusy KeyPresent + KeyPresentButOnlyOtherUsers ) func (status KeyStatus) String() string { @@ -118,6 +129,8 @@ func (status KeyStatus) String() string { return "AbsentButFilesBusy" case KeyPresent: return "Present" + case KeyPresentButOnlyOtherUsers: + return "PresentButOnlyOtherUsers" default: return strconv.Itoa(int(status)) } |