diff options
Diffstat (limited to '')
5 files changed, 333 insertions, 0 deletions
diff --git a/debian/patches/Check-for-physical-memory-available-also-in-PBKDF-benchma.patch b/debian/patches/Check-for-physical-memory-available-also-in-PBKDF-benchma.patch new file mode 100644 index 0000000..2032283 --- /dev/null +++ b/debian/patches/Check-for-physical-memory-available-also-in-PBKDF-benchma.patch @@ -0,0 +1,74 @@ +From: Milan Broz <gmazyland@gmail.com> +Date: Mon, 3 Apr 2023 13:31:16 +0200 +Subject: Check for physical memory available also in PBKDF benchmark. + +Origin: https://gitlab.com/cryptsetup/cryptsetup/-/commit/7893c33d71cde09e240234c484c6c468f22c2fe7 +Bug: https://gitlab.com/cryptsetup/cryptsetup/-/issues/802#note_1328592911 +Bug-Debian: https://bugs.debian.org/1028250 +--- + lib/internal.h | 1 + + lib/utils_benchmark.c | 9 +++++++++ + lib/utils_pbkdf.c | 4 ++-- + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/lib/internal.h b/lib/internal.h +index 98095fa..f261cae 100644 +--- a/lib/internal.h ++++ b/lib/internal.h +@@ -89,6 +89,7 @@ int crypt_benchmark_pbkdf_internal(struct crypt_device *cd, + struct crypt_pbkdf_type *pbkdf, + size_t volume_key_size); + const char *crypt_get_cipher_spec(struct crypt_device *cd); ++uint32_t pbkdf_adjusted_phys_memory_kb(void); + + /* Device backend */ + struct device; +diff --git a/lib/utils_benchmark.c b/lib/utils_benchmark.c +index 728e4df..a0326ce 100644 +--- a/lib/utils_benchmark.c ++++ b/lib/utils_benchmark.c +@@ -101,6 +101,7 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd, + { + int r, priority; + const char *kdf_opt; ++ uint32_t memory_kb; + + if (!pbkdf || (!password && password_size)) + return -EINVAL; +@@ -113,6 +114,14 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd, + + log_dbg(cd, "Running %s(%s) benchmark.", pbkdf->type, kdf_opt); + ++ memory_kb = pbkdf_adjusted_phys_memory_kb(); ++ if (memory_kb < pbkdf->max_memory_kb) { ++ log_dbg(cd, "Not enough physical memory detected, " ++ "PBKDF max memory decreased from %dkB to %dkB.", ++ pbkdf->max_memory_kb, memory_kb); ++ pbkdf->max_memory_kb = memory_kb; ++ } ++ + crypt_process_priority(cd, &priority, true); + r = crypt_pbkdf_perf(pbkdf->type, pbkdf->hash, password, password_size, + salt, salt_size, volume_key_size, pbkdf->time_ms, +diff --git a/lib/utils_pbkdf.c b/lib/utils_pbkdf.c +index d8f41c7..b2d4fa0 100644 +--- a/lib/utils_pbkdf.c ++++ b/lib/utils_pbkdf.c +@@ -61,7 +61,7 @@ const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_typ + return NULL; + } + +-static uint32_t adjusted_phys_memory(void) ++uint32_t pbkdf_adjusted_phys_memory_kb(void) + { + uint64_t free_kb, memory_kb = crypt_getphysmemory_kb(); + +@@ -258,7 +258,7 @@ int init_pbkdf_type(struct crypt_device *cd, + } + + if (cd_pbkdf->max_memory_kb) { +- memory_kb = adjusted_phys_memory(); ++ memory_kb = pbkdf_adjusted_phys_memory_kb(); + if (cd_pbkdf->max_memory_kb > memory_kb) { + log_dbg(cd, "Not enough physical memory detected, " + "PBKDF max memory decreased from %dkB to %dkB.", diff --git a/debian/patches/Print-warning-when-keyslot-requires-more-memory-than-avai.patch b/debian/patches/Print-warning-when-keyslot-requires-more-memory-than-avai.patch new file mode 100644 index 0000000..91bab91 --- /dev/null +++ b/debian/patches/Print-warning-when-keyslot-requires-more-memory-than-avai.patch @@ -0,0 +1,49 @@ +From: Milan Broz <gmazyland@gmail.com> +Date: Tue, 28 Feb 2023 14:18:10 +0100 +Subject: Print warning when keyslot requires more memory than available + +This warning is displayed only if maximum memory was adjusted: +no swap, not enough memory, but is not printed if user set keyslot +memory cost above default limit intentionally. + +In the latter case we have to check all available memory and guess +if swap is enough - this is not job af cryptsetup and also +it should not excessively parse any /sys files during keyslot open. + +Origin: https://gitlab.com/cryptsetup/cryptsetup/-/commit/27f8e5c08f0e0054225c9a2b1eda5b4200d4565b +Bug: https://gitlab.com/cryptsetup/cryptsetup/-/issues/802#note_1287298872 +Bug-Debian: https://bugs.debian.org/1032734 +--- + lib/luks2/luks2_keyslot_luks2.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c +index 491dcad..3be1135 100644 +--- a/lib/luks2/luks2_keyslot_luks2.c ++++ b/lib/luks2/luks2_keyslot_luks2.c +@@ -307,7 +307,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, + char *volume_key, size_t volume_key_len) + { + struct volume_key *derived_key = NULL; +- struct crypt_pbkdf_type pbkdf; ++ struct crypt_pbkdf_type pbkdf, *cd_pbkdf; + char *AfKey = NULL; + size_t AFEKSize; + const char *af_hash = NULL; +@@ -360,6 +360,16 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, + goto out; + } + ++ /* ++ * Print warning when keyslot requires more memory than available ++ * (if maximum memory was adjusted - no swap, not enough memory), ++ * but be silent if user set keyslot memory cost above default limit intentionally. ++ */ ++ cd_pbkdf = crypt_get_pbkdf(cd); ++ if (cd_pbkdf->max_memory_kb && pbkdf.max_memory_kb > cd_pbkdf->max_memory_kb && ++ pbkdf.max_memory_kb <= DEFAULT_LUKS2_MEMORY_KB) ++ log_std(cd, _("Warning: keyslot operation could fail as it requires more than available memory.\n")); ++ + /* + * If requested, serialize unlocking for memory-hard KDF. Usually NOOP. + */ diff --git a/debian/patches/Try-to-avoid-OOM-killer-on-low-memory-systems-without-swa.patch b/debian/patches/Try-to-avoid-OOM-killer-on-low-memory-systems-without-swa.patch new file mode 100644 index 0000000..b8f81b9 --- /dev/null +++ b/debian/patches/Try-to-avoid-OOM-killer-on-low-memory-systems-without-swa.patch @@ -0,0 +1,163 @@ +From: Milan Broz <gmazyland@gmail.com> +Date: Mon, 20 Feb 2023 16:45:36 +0100 +Subject: Try to avoid OOM killer on low-memory systems without swap. + +Benchmark for memory-hard KDF is tricky, seems that relying +on maximum half of physical memory is not enough. + +Let's allow only free physical available space if there is no swap. +This should not cause changes on normal systems, at least. + +Origin: https://gitlab.com/cryptsetup/cryptsetup/-/commit/899bad8c06957a94a198d1eaa293ed8db205f1de +Bug: https://gitlab.com/cryptsetup/cryptsetup/-/issues/802 +Bug-Debian: https://bugs.debian.org/1028250 +--- + lib/internal.h | 2 ++ + lib/utils.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + lib/utils_pbkdf.c | 11 ++++++++++- + tests/api-test-2.c | 12 ++++++++---- + 4 files changed, 67 insertions(+), 5 deletions(-) + +diff --git a/lib/internal.h b/lib/internal.h +index b5cb4e3..98095fa 100644 +--- a/lib/internal.h ++++ b/lib/internal.h +@@ -168,6 +168,8 @@ int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid); + size_t crypt_getpagesize(void); + unsigned crypt_cpusonline(void); + uint64_t crypt_getphysmemory_kb(void); ++uint64_t crypt_getphysmemoryfree_kb(void); ++bool crypt_swapavailable(void); + + int init_crypto(struct crypt_device *ctx); + +diff --git a/lib/utils.c b/lib/utils.c +index bfcf60d..e9d5b5b 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -59,6 +59,53 @@ uint64_t crypt_getphysmemory_kb(void) + return phys_memory_kb; + } + ++uint64_t crypt_getphysmemoryfree_kb(void) ++{ ++ long pagesize, phys_pages; ++ uint64_t phys_memoryfree_kb; ++ ++ pagesize = sysconf(_SC_PAGESIZE); ++ phys_pages = sysconf(_SC_AVPHYS_PAGES); ++ ++ if (pagesize < 0 || phys_pages < 0) ++ return 0; ++ ++ phys_memoryfree_kb = pagesize / 1024; ++ phys_memoryfree_kb *= phys_pages; ++ ++ return phys_memoryfree_kb; ++} ++ ++bool crypt_swapavailable(void) ++{ ++ int fd; ++ ssize_t size; ++ char buf[4096], *p; ++ uint64_t total; ++ ++ if ((fd = open("/proc/meminfo", O_RDONLY)) < 0) ++ return true; ++ ++ size = read(fd, buf, sizeof(buf)); ++ close(fd); ++ if (size < 1) ++ return true; ++ ++ if (size < (ssize_t)sizeof(buf)) ++ buf[size] = 0; ++ else ++ buf[sizeof(buf) - 1] = 0; ++ ++ p = strstr(buf, "SwapTotal:"); ++ if (!p) ++ return true; ++ ++ if (sscanf(p, "SwapTotal: %" PRIu64 " kB", &total) != 1) ++ return true; ++ ++ return total > 0; ++} ++ + void crypt_process_priority(struct crypt_device *cd, int *priority, bool raise) + { + int _priority, new_priority; +diff --git a/lib/utils_pbkdf.c b/lib/utils_pbkdf.c +index 4d7e18d..d8f41c7 100644 +--- a/lib/utils_pbkdf.c ++++ b/lib/utils_pbkdf.c +@@ -63,7 +63,7 @@ const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_typ + + static uint32_t adjusted_phys_memory(void) + { +- uint64_t memory_kb = crypt_getphysmemory_kb(); ++ uint64_t free_kb, memory_kb = crypt_getphysmemory_kb(); + + /* Ignore bogus value */ + if (memory_kb < (128 * 1024) || memory_kb > UINT32_MAX) +@@ -75,6 +75,15 @@ static uint32_t adjusted_phys_memory(void) + */ + memory_kb /= 2; + ++ /* ++ * Never use more that available free space on system without swap. ++ */ ++ if (!crypt_swapavailable()) { ++ free_kb = crypt_getphysmemoryfree_kb(); ++ if (free_kb > (64 * 1024) && free_kb < memory_kb) ++ return free_kb; ++ } ++ + return memory_kb; + } + +diff --git a/tests/api-test-2.c b/tests/api-test-2.c +index 824ae65..923165c 100644 +--- a/tests/api-test-2.c ++++ b/tests/api-test-2.c +@@ -2802,7 +2802,8 @@ static void Pbkdf(void) + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); +- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); ++ GE_(pbkdf->max_memory_kb, 64 * 1024); ++ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); + // set and verify argon2 type + OK_(crypt_set_pbkdf_type(cd, &argon2)); +@@ -2827,7 +2828,8 @@ static void Pbkdf(void) + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); +- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); ++ GE_(pbkdf->max_memory_kb, 64 * 1024); ++ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); + // try to pass illegal values + argon2.parallel_threads = 0; +@@ -2858,14 +2860,16 @@ static void Pbkdf(void) + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); +- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); ++ GE_(pbkdf->max_memory_kb, 64 * 1024); ++ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); + crypt_set_iteration_time(cd, 1); + OK_(crypt_load(cd, CRYPT_LUKS, NULL)); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, 1); +- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); ++ GE_(pbkdf->max_memory_kb, 64 * 1024); ++ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); + CRYPT_FREE(cd); + diff --git a/debian/patches/Use-only-half-of-detected-free-memory-on-systems-without-.patch b/debian/patches/Use-only-half-of-detected-free-memory-on-systems-without-.patch new file mode 100644 index 0000000..caf47ce --- /dev/null +++ b/debian/patches/Use-only-half-of-detected-free-memory-on-systems-without-.patch @@ -0,0 +1,43 @@ +From: Milan Broz <gmazyland@gmail.com> +Date: Mon, 17 Apr 2023 13:41:17 +0200 +Subject: Use only half of detected free memory on systems without swap. + +As tests shows, limiting used Argon2 memory to free memory on +systems without swap is still not enough. +Use just half of it, this should bring needed margin while +still use Argon2. + +Note, for very-low memory constrained systems user should +avoid memory-hard PBKDF (IOW manually select PBKDF2), we +do not do this automatically. + +Origin: https://gitlab.com/cryptsetup/cryptsetup/-/commit/6721d3a8b29b13fe88aeeaefe09d457e99d1c6fa +Bug: https://gitlab.com/cryptsetup/cryptsetup/-/issues/802#note_1328592911 +Bug-Debian: https://bugs.debian.org/1028250 +--- + lib/utils_pbkdf.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/utils_pbkdf.c b/lib/utils_pbkdf.c +index b2d4fa0..7399bd2 100644 +--- a/lib/utils_pbkdf.c ++++ b/lib/utils_pbkdf.c +@@ -76,10 +76,17 @@ uint32_t pbkdf_adjusted_phys_memory_kb(void) + memory_kb /= 2; + + /* +- * Never use more that available free space on system without swap. ++ * Never use more that half of available free memory on system without swap. + */ + if (!crypt_swapavailable()) { + free_kb = crypt_getphysmemoryfree_kb(); ++ ++ /* ++ * Using exactly free memory causes OOM too, use only half of the value. ++ * Ignore small values (< 64MB), user should use PBKDF2 in such environment. ++ */ ++ free_kb /= 2; ++ + if (free_kb > (64 * 1024) && free_kb < memory_kb) + return free_kb; + } diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..f64f6f7 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,4 @@ +Try-to-avoid-OOM-killer-on-low-memory-systems-without-swa.patch +Print-warning-when-keyslot-requires-more-memory-than-avai.patch +Check-for-physical-memory-available-also-in-PBKDF-benchma.patch +Use-only-half-of-detected-free-memory-on-systems-without-.patch |