From 7568ca2aab4a3266eb95cbda64298e2292743c7b Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 29 Aug 2017 11:17:10 -0700 Subject: [PATCH] crypto: Handle when "ulimit -l" is too low --- cmd/fscrypt/errors.go | 7 +++++++ crypto/crypto.go | 1 + crypto/crypto_test.go | 14 ++++++++++++++ crypto/key.go | 3 +++ 4 files changed, 25 insertions(+) diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 10dbf1e..b2aa57e 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -32,6 +32,7 @@ import ( "github.com/urfave/cli" "github.com/google/fscrypt/actions" + "github.com/google/fscrypt/crypto" "github.com/google/fscrypt/filesystem" "github.com/google/fscrypt/metadata" "github.com/google/fscrypt/util" @@ -77,6 +78,12 @@ func getErrorSuggestions(err error) string { switch errors.Cause(err) { case filesystem.ErrNotSetup: return fmt.Sprintf(`Run "fscrypt setup %s" to use fscrypt on this filesystem.`, mountpointArg) + case crypto.ErrKeyLock: + return `Too much memory was requested to be locked in RAM. The + current limit for this user can be checked with "ulimit + -l". The limit can be modified by either changing the + "memlock" item in /etc/security/limits.conf or by + changing the "LimitMEMLOCK" value in systemd.` case metadata.ErrEncryptionNotSupported: return `Encryption for this type of filesystem is not supported on this kernel version.` diff --git a/crypto/crypto.go b/crypto/crypto.go index 62226b9..a85d345 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -62,6 +62,7 @@ var ( ErrGetrandomFail = util.SystemError("getrandom() failed") ErrKeyAlloc = util.SystemError("could not allocate memory for key") ErrKeyFree = util.SystemError("could not free memory of key") + ErrKeyLock = errors.New("could not lock key in memory") ) // panicInputLength panics if "name" has invalid length (expected != actual) diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index a069b1b..719db00 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -294,6 +294,20 @@ func TestRandomKeyGen(t *testing.T) { } } +func TestBigKeyGen(t *testing.T) { + key, err := NewRandomKey(4096 * 4096) + switch err { + case nil: + key.Wipe() + return + case ErrKeyLock: + // Don't fail just because "ulimit -l" is too low. + return + default: + t.Fatal(err) + } +} + // didCompress checks if the given data can be compressed. Specifically, it // returns true if running zlib on the provided input produces a shorter output. func didCompress(input []byte) bool { diff --git a/crypto/key.go b/crypto/key.go index 99efc1a..ec37330 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -109,6 +109,9 @@ func newBlankKey(length int) (*Key, error) { // See MAP_ANONYMOUS in http://man7.org/linux/man-pages/man2/mmap.2.html data, err := unix.Mmap(-1, 0, length, keyProtection, flags) + if err == unix.EAGAIN { + return nil, ErrKeyLock + } if err != nil { log.Printf("unix.Mmap() with length=%d failed: %v", length, err) return nil, ErrKeyAlloc -- 2.39.5