aboutsummaryrefslogtreecommitdiff
path: root/actions
AgeCommit message (Collapse)Author
2022-12-04Stop using deprecated package io/ioutilEric Biggers
Since Go 1.16 (which recently became the minimum supported Go version for this project), the package io/ioutil is deprecated in favor of equivalent functionality in the io and os packages. staticcheck warns about this. Address all the warnings by switching to the non-deprecated replacement functions.
2022-04-08Switch to google.golang.org/protobuf/protoEric Biggers
github.com/golang/protobuf/proto has been deprecated in favor of google.golang.org/protobuf/proto, so migrate to the non-deprecated one.
2022-02-23Make all new metadata files owned by user when neededEric Biggers
Since commit 4c7c6631cc5a ("Set owner of login protectors to correct user"), login protectors are made owned by the user when root creates one on a user's behalf. That's good, but the same isn't true of other files that get created at the same time: - The policy protecting the directory - The protector link file, if the policy is on a different filesystem - The recovery protector, if the policy is on a different filesystem - The recovery instructions file In preparation for setting all metadata files to mode 0600, start making all these files owned by the user in this scenario as well.
2022-02-23Extend ownership validation to entire directory structureEric Biggers
A previous commit extended file ownership validation to policy and protector files (by default -- there's an opt-out in /etc/fscrypt.conf). However, that didn't apply to the parent directories: MOUNTPOINT MOUNTPOINT/.fscrypt MOUNTPOINT/.fscrypt/policies MOUNTPOINT/.fscrypt/protectors The problem is that if the parent directories aren't trusted (owned by another non-root user), then untrusted changes to their contents can be made at any time, including the introduction of symlinks and so on. While it's debatable how much of a problem this really is, given the other validations that are done, it seems to be appropriate to validate the parent directories too. Therefore, this commit applies the same ownership validations to the above four directories as are done on the metadata files themselves. In addition, it is validated that none of these directories are symlinks except for ".fscrypt" where this is explicitly supported.
2022-02-23Strictly validate metadata file ownership by defaultEric Biggers
The metadata validation checks introduced by the previous commits are good, but to reduce the attack surface it would be much better to avoid reading and parsing files owned by other users in the first place. There are some possible use cases for users sharing fscrypt metadata files, but I think that for the vast majority of users it is unneeded and just opens up attack surface. Thus, make fscrypt (and pam_fscrypt) not process policies or protectors owned by other users by default. Specifically, * If fscrypt or pam_fscrypt is running as a non-root user, only policies and protectors owned by the user or by root can be used. * If fscrypt is running as root, any policy or protector can be used. (This is to match user expectations -- starting a sudo session should gain rights, not remove rights.) * If pam_fscrypt is running as root, only policies and protectors owned by root can be used. Note that this only applies when the root user themselves has an fscrypt login protector, which is rare. Add an option 'allow_cross_user_metadata' to /etc/fscrypt.conf which allows restoring the old behavior for anyone who really needs it.
2022-02-23Make 'fscrypt setup' offer a choice of directory modesEric Biggers
World-writable directories are not appropriate for some systems, so offer a choice of single-user-writable and world-writable modes, with single-user-writable being the default. Add a new documentation section to help users decide which one to use.
2021-12-23cmd/fscrypt: don't load protector in remove-protector-from-policyEric Biggers
Make remove-protector-from-policy work even if the protector cannot be loaded (for example, due to having been deleted already). Fixes https://github.com/google/fscrypt/issues/258 Fixes https://github.com/google/fscrypt/issues/272
2021-12-22context_text: remove pre-existing test.confEric Biggers
This fixes a test failure in the case where test.conf gets left over.
2021-10-05Adjust recovery passphrase generationEric Biggers
As per the feedback at https://github.com/google/fscrypt/issues/115 where users didn't understand that the recovery passphrase is important, restore the original behavior where recovery passphrase generation happens automatically without a prompt. This applies to the case where 'fscrypt encrypt' is using a login protector on a non-root filesystem. However, leave the --no-recovery option so that the recovery passphrase can still be disabled if the user really wants to. Also, clarify the information provided about the recovery passphrase. Update https://github.com/google/fscrypt/issues/115
2021-05-24Run the Garbage Collector in the timing loopJoe Richey
Running `crypto.PassphraseHash` in a loop allocates a lot of memory. Golang is not always prudent about collecting the garbage from previous runs, resulting in a OOM error on memory-pressured systems. With a `maxMemoryBytes` of 128 MiB, this change reduces the maximum resident memory for `fscrypt setup` to 141 MiB (was perviously 405 MiB) Signed-off-by: Joe Richey <joerichey@google.com>
2021-05-24Only use 1/8 of the system RAMJoe Richey
On systems with high memory pressure, using half of the entire RAM for hashing can result in fscrypt getting OOM killed. Signed-off-by: Joe Richey <joerichey@google.com>
2020-05-09filesystem: improve errorsEric Biggers
Introduce filesystem.ErrEncryptionNotEnabled and filesystem.ErrEncryptionNotSupported which include the Mount as context, and translate the corresponding metadata/ errors into them. Then make these errors show much better suggestions. Also replace lots of other filesystem/ errors with either custom types or with unnamed one-off errors that include more context. Fix backwards wrapping in lots of cases. Finally, don't include the mountpoint in places where it's not useful, like OS-level errors that already include the path.
2020-05-09actions/policy: improve errorsEric Biggers
ErrMissingPolicyMetadata: Include the mount, directory path, and metadata path. Also move the explanation into actions/ since it doesn't refer to any CLI command. ErrPolicyMetadataMismatch: Include a lot more information. Also start checking for consistency of the policy key descriptors, not just the encryption options. Add a test for this. ErrDifferentFilesystem: Include the mountpoints. ErrOnlyProtector: Clarify the message and include the protector descriptor. ErrAlreadyProtected: ErrNotProtected: Include the policy and protector descriptors. ErrAccessDeniedPossiblyV2: Make it slightly clearer what failed. Also move the explanation into actions/ since it doesn't refer to any CLI command.
2020-05-09actions/protector: improve errorsEric Biggers
ErrProtectorName: Rename to ErrLoginProtectorName for clarity, and include the name and user. ErrMissingProtectorName: Include the correct protector source. ErrDuplicateName: Rename to ErrProtectorNameExists for clarity, and remove a level of wrapping by including the name directly. ErrDuplicateUID: Rename to ErrLoginProtectorExists for clarity, and remove a level of wrapping by including the user directly.
2020-05-09actions/config: improve config file related errorsEric Biggers
ErrBadConfig: Fix backwards wrapping, include the bad config, and make it clear that this is an internal error. ErrBadConfigFile: Fix backwards wrapping, include the config file location, and adjust the suggestion slightly. ErrConfigFileExists: Include the config file location. ErrNoConfigFile: Include the config file location, and adjust the suggestion slightly.
2020-05-09Try to detect incomplete locking of v1-encrypted directoryEric Biggers
'fscrypt lock' on a v1-encrypted directory doesn't warn about in-use files, as the kernel doesn't provide a way to easily detect it. Instead, implement a heuristic where we check whether a subdirectory can be created. If yes, then the directory must not be fully locked. Make both 'fscrypt lock' and 'fscrypt status' use this heuristic. Resolves https://github.com/google/fscrypt/issues/215
2020-05-09cmd/fscrypt: add FSCRYPT_ROOT_MNT environmental variableEric Biggers
Allow overriding the mountpoint where login protectors are stored by setting the FSCRYPT_ROOT_MNT environmental variable. The CLI tests need this to avoid touching the real "/".
2020-03-23Improve error message when unlocking v2 policy is unsupportedEric Biggers
If trying to unlock a v2-encrypted directory fails because the kernel lacks support for v2 policies, show a better error message. This can happen if someone downgrades their kernel or tries to access encrypted directories on removable storage from a computer with an older kernel. Detecting this case is difficult since all we have to go with is EACCES when opening the directory. Implement a heuristic where if get EACCES, we actually have read access to the directory, and the kernel doesn't support v2 policies, we show the improved error message. Before: # fscrypt unlock dir [ERROR] fscrypt unlock: open dir: permission denied After: # fscrypt unlock dir [ERROR] fscrypt unlock: open dir: permission denied This may be caused by the directory using a v2 encryption policy and the current kernel not supporting it. If indeed the case, then this directory can only be used on kernel v5.4 and later. You can create directories accessible on older kernels by changing policy_version to 1 in /etc/fscrypt.conf.
2020-03-23Create /etc/fscrypt.conf with policy_version 2 on kernel v5.4+Eric Biggers
v2 encryption policies are now recommended, due to various security and usability advantages over v1 policies. Many people have been running into the usability problems with v1, so it's desirable to get people onto v2 without having to manually opt-in. Therefore, when 'fscrypt setup' creates /etc/fscrypt.conf, enable policy_version 2 automatically if the kernel supports it. I decided to go with this solution over the policy_version "auto" I suggested originally because this way is simpler, it can still be changed to "auto" later if desired, and "auto" might require changing how we parse the config file (since currently the config file is mapped directly to a protobuf where policy_version is an 'int' and is shared with EncryptionOptions). Resolves https://github.com/google/fscrypt/issues/182
2020-03-23Simplify choosing the key description prefixEric Biggers
There's no real need to allow users to choose the key description prefix (a.k.a. the "service"), since on ext4 and f2fs we can just use "ext4" and "f2fs" for compatibility with all kernels both old and new, and on other filesystems we can just use "fscrypt". So, let's do that. Since this removes the point of the "--legacy" option to 'fscrypt setup' and the "compatibility" field in /etc/fscrypt.conf, remove those too. Specifically, we start ignoring the "compatibility" in existing config files and not writing it to new ones. The corresponding protobuf field number and name are reserved. We stop accepting the "--legacy" option at all, although since it was default true and there was no real reason for anyone to change it to false, probably no one will notice. If anyone does, they should just stop specifying the option. Note that this change only affects user keyrings and thus only affects v1 encryption policies, which are deprecated in favor of v2 anyway.
2020-01-28actions/policy: revert new protector links on failureEric Biggers
Ensure that when an encryption policy is reverted (e.g. due to encryptPath() failing after the policy was created), we also delete any new protector links that were created for the policy, as this is not handled by the logic that reverts new protectors.
2020-01-28filesystem: don't overwrite existing protector linksEric Biggers
When adding a protector to a policy, don't unconditionally overwrite the protector link, because it may already exist. Instead, if it already exists and points to the mount, just use it. If it already exists and points to the wrong place, return an error. Also add a bool to the return value of AddLinkedProtector() so that callers can check whether the link was newly created or not.
2020-01-28actions/recovery: revert protector if it can't be added to policyEric Biggers
Ensure that a failed AddRecoveryPassphrase() doesn't leave around an unneeded protector file.
2020-01-27actions/recovery: ensure recovery passphrase is really custom_passphraseEric Biggers
If the login protector was just created by the same 'fscrypt encrypt' command, then policy.Context.Config.Source will be pam_passphrase. This needs to be overridden to custom_passphrase when creating the protector for the recovery passphrase. This fixes the following error: fscrypt encrypt: login protectors do not need a name Resolves https://github.com/google/fscrypt/issues/187 Update https://github.com/google/fscrypt/issues/186
2020-01-22Automatically generate recovery passphrase when usefulEric Biggers
If a user re-installs their system (or otherwise loses the /.fscrypt directory on the root filesystem) they also lose access to any login passphrase-protected directories on other filesystems, unless additional protectors were manually added. This can be unexpected, as it may be expected that the old login passphrase would still work. We can't really fix this by storing a login protector on every filesystem because: - If a user were to have N login protectors, it would take them N times longer to log in, as every login protector would need to be unlocked. - If a user were to change their login passphrase while any external volumes were unmounted, login protectors would get out of sync. - It's preferable that an external volume isn't unlockable by itself using only a login passphrase, as login passphrases are often weak. Instead, generate a recovery passphrase when creating a login passphrase-protected directory on a non-root filesystem. The recovery passphrase is added as a custom_passphrase protector, thus giving the policy two protectors: one pam_passphrase and one custom_passphrase. Then this passphrase is written to a file in the new encrypted directory. Writing the passphrase to a file here is okay since it's encrypted, but it's obviously useless by itself; it's up to the user to store this passphrase somewhere else if they need it. Use a recovery passphrase instead of a "recovery code" that encodes the policy key directly because a passphrase is more user-friendly: it can safely be made much shorter than a key, and it works just like any other fscrypt protector. Also, it's not as critical to allow recovery when the .fscrypt directory on the *same* filesystem is deleted. Resolves https://github.com/google/fscrypt/issues/164
2020-01-05cmd/fscrypt, keyring: add --all-users option to 'fscrypt lock'Eric Biggers
Allow root to provide the --all-users option to 'fscrypt lock' to force an encryption key to be removed from the filesystem (i.e., force an encrypted directory to be locked), even if other users have added it. To implement this option, we just need to use the FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl rather than FS_IOC_REMOVE_ENCRYPTION_KEY. In theory this option could be implemented for the user keyrings case too, but it would be difficult and the user keyrings are being deprecated for fscrypt, so don't bother.
2020-01-05Keyring support for v2 encryption policiesEric Biggers
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.
2020-01-05Metadata support for v2 encryption policiesEric Biggers
Linux v5.4 and later supports v2 encryption policies. These have several advantages over v1 encryption policies: - Their encryption keys can be added/removed to/from the filesystem by non-root users, thus gaining the benefits of the filesystem keyring while also retaining support for non-root use. - They use a more standard, secure, and flexible key derivation function. Because of this, some future kernel-level fscrypt features will be implemented for v2 policies only. - They prevent a denial-of-service attack where a user could associate the wrong key with another user's encrypted files. Prepare the fscrypt tool to support v2 encryption policies by: - Adding a policy_version field to the EncryptionOptions, i.e. to the config file and to the policy metadata files. - Using the kernel-specified algorithm to compute the key descriptor for v2 policies. - Handling setting and getting v2 policies. Actually adding/removing the keys for v2 policies to/from the kernel is left for the next patch.
2020-01-05pam_fscrypt: update to handle filesystem keyringEric Biggers
FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY require root for v1 policy keys, so update the PAM module to re-acquire root privileges while provisioning/deprovisioning policies that need this. Also, only set up the user keyring if it will actually be used.
2020-01-05cmd/fscrypt: add 'fscrypt lock' commandEric Biggers
Add support for 'fscrypt lock'. This command "locks" a directory, undoing 'fscrypt unlock'. When the filesystem keyring is used, 'fscrypt lock' also detects when a directory wasn't fully locked due to some files still being in-use. It can then be run again later to try to finish locking the files.
2020-01-05keyring: support filesystem keyring with v1 encryption policiesEric Biggers
Linux v5.4 and later allows fscrypt keys to be added/removed directly to/from the filesystem via the new ioctls FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY. Among other benefits, these fix the key visibility problems that many users have been running into, where system services and containers can't access encrypted files. Allow the user to opt-in to using these new ioctls for their existing encrypted directories by setting in their /etc/fscrypt.conf: "use_fs_keyring_for_v1_policies": true Note that it can't really be on by default, since for v1 policies the ioctls require root, whereas user keyrings don't. I.e., setting this to true means that users will need to use 'sudo fscrypt unlock', not 'fscrypt unlock'. v2 policies won't have this restriction.
2020-01-05Add keyring packageEric Biggers
In preparation for introducing support for the new filesystem-level keyrings, move the existing user keyring management code from security/keyring.go and crypto/crypto.go into a new package, 'keyring'. This package provides functions AddEncryptionKey, RemoveEncryptionKey, and GetEncryptionKeyStatus which delegate to either the filesystem keyring (added by a later patch) or to the user keyring. This provides a common interface to both types of keyrings, to the extent possible.
2019-11-27Rename some variables from 'target' to 'targetUser'Eric Biggers
Refer to the target User as 'targetUser' rather than simply 'target'. This will help avoid confusion when we add support for the filesystem keyring, since then the Mount will also be a "target".
2019-11-27Use latest fscrypt declarations from sys/unixEric Biggers
Use the new name for fscrypt constants and structures which have been given a new name. Also use the named constant for the DIRECT_KEY fscrypt policy flag. No change in behavior. This is just preparing for future work.
2019-10-29filesystem: rename Mount.Filesystem to Mount.FilesystemTypeEric Biggers
Make it clear that this refers to a type of filesystem such as "ext4", rather than to a specific filesystem instance.
2019-10-23actions/config: ensure config file is created with mode 0644 (#152)ebiggers
If the user has set a restrictive umask, e.g. 0077, then /etc/fscrypt.conf would be created without the world-readable bit set. Fix it by overriding the umask when creating the file. Resolves https://github.com/google/fscrypt/issues/151
2019-09-09cmd/fscrypt: show encryption options with 'fscrypt status DIR' (#145)ebiggers
Show the encryption options when running 'fscrypt status' on a directory. E.g.: Policy: 490515286453d3f7 Options: padding:32 contents:Adiantum filenames:Adiantum Unlocked: Yes
2019-09-08Fix various typos and grammatical errors (#141)ebiggers
These were found by a combination of manual review and a custom script that checks for common errors. Also removed an outdated sentence from the comment for setupBefore().
2018-08-30Use proto.Equal instead of reflect.DeepEqualsJoe Richey joerichey@google.com
2018-02-11vet: eliminate unnecessary shadowingJoseph Richey
Running "go vet -shadow ./..." finds all places where a variable might be incorrectly or unnecessarily shadowed. This fixes some of them.
2018-02-09dep: Run dep ensureJoseph Richey
2018-01-10Format files correctlyJoe Richey joerichey@google.com
2018-01-10Limit the amount of RAM that will be usedJoe Richey joerichey@google.com
Fixes #73. Adds maxMemoryBytes as 128MiB and cleans up the helper functions/variables to make it more clear which values are a number of bytes, and which values are a number of KiB.
2017-09-01security: Change user keyring lookup algorithmJoseph Richey
Now instead of spawning a seperate thread we alternate between changing the euid and ruid to both find the keyring and link it to the process keyring. Note that we also ensure that the user keyring is linked into the root keyring whenever possible.
2017-08-30actions: context now hold a target user.UserJoe Richey
This user is used with policies to interface with the keryings and with protectors to indicate which user's login passphrase should be used to protectors of type pam_passphrase.
2017-08-22Various small nits a helper functions for PAMJoe Richey joerichey@google.com
2017-08-17cmd/fscrypt: purge command now clears cacheJoe Richey joerichey@google.com
2017-08-15crypto: Switch from session to user keyringJoe Richey joerichey@google.com
2017-08-07actions: calculate password hash difficulty correctlyEric Biggers
'fscrypt setup' is supposed to calibrate the Argon2 password hashing difficulty to 1s by default, but actually it was setting it to only 1s / num_cpus because the hashing is done with all CPUs and it is timed using the CLOCK_PROCESS_CPUTIME_ID clock, which measures the time spent by all threads in the process. Fix this by dividing the elapsed time by HashingCosts.Parallelism, which is used as the number of threads.
2017-07-18tests: Unit tests and Integration tests workJoe Richey joerichey@google.com
Now the testing functions will skip the integration tests if a testing filesystem is not specified.