From 1852e977f899ba509e86e71b1a3d35dcf068a7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Knecht?= Date: Wed, 26 Apr 2023 11:22:25 +0200 Subject: [PATCH] util: Limit cryptsetup PBKDF memory usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default, `cryptsetup luksFormat` uses Argon2i as Password-Based Key Derivation Function (PBKDF), which not only has a CPU cost, but also a memory cost (to make brute-force attacks harder). The memory cost is based on the available system memory by default, which in the context of Ceph CSI can be a problem for two reasons: 1. Pods can have a memory limit (much lower that the memory available on the node, usually) which isn't taken into account by `cryptsetup`, so it can get OOM-killed when formating a new volume; 2. The amount of memory that was used during `cryptsetup luksFormat` will then be needed for `cryptsetup luksOpen`, so if the volume was formated on a node with a lot of memory, but then needs to be opened on a different node with less memory, `cryptsetup` will get OOM-killed. This commit sets the PBKDF memory limit to a fixed value to ensure consistent memory usage regardless of the specifications of the nodes where the volume happens to be formatted in the first place. The limit is set to a relatively low value (32 MiB) so that the `csi-rbdplugin` container in the `nodeplugin` pod doesn't require an extravagantly high memory limit in order to format/open volumes (particularly with operations happening in parallel), while at the same time not being so low as to render it completely pointless. Signed-off-by: BenoƮt Knecht --- internal/util/cryptsetup.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/util/cryptsetup.go b/internal/util/cryptsetup.go index f9677f743a1..e5669b42533 100644 --- a/internal/util/cryptsetup.go +++ b/internal/util/cryptsetup.go @@ -20,9 +20,13 @@ import ( "bytes" "fmt" "os/exec" + "strconv" "strings" ) +// Limit memory used by Argon2i PBKDF to 32 MiB. +const cryptsetupPBKDFMemoryLimit = 32 << 10 // 32768 KiB + // LuksFormat sets up volume as an encrypted LUKS partition. func LuksFormat(devicePath, passphrase string) (string, string, error) { return execCryptsetupCommand( @@ -33,6 +37,8 @@ func LuksFormat(devicePath, passphrase string) (string, string, error) { "luks2", "--hash", "sha256", + "--pbkdf-memory", + strconv.Itoa(cryptsetupPBKDFMemoryLimit), devicePath, "-d", "/dev/stdin")