Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cryptsetup for openSUSE:Factory checked in at 2023-07-15 23:14:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cryptsetup (Old) and /work/SRC/openSUSE:Factory/.cryptsetup.new.3193 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cryptsetup" Sat Jul 15 23:14:26 2023 rev:124 rq:1098512 version:2.6.1 Changes: -------- --- /work/SRC/openSUSE:Factory/cryptsetup/cryptsetup.changes 2023-06-17 22:20:15.527518317 +0200 +++ /work/SRC/openSUSE:Factory/.cryptsetup.new.3193/cryptsetup.changes 2023-07-15 23:14:28.871276312 +0200 @@ -1,0 +2,12 @@ +Thu Jul 13 09:46:24 UTC 2023 - Pedro Monreal <pmonr...@suse.com> + +- luksFormat: Handle system with low memory and no swap space [bsc#1211079] + * Check for physical memory available also in PBKDF benchmark. + * Try to avoid OOM killer on low-memory systems without swap. + * Use only half of detected free memory on systems without swap. + * Add patches: + - cryptsetup-Check-for-physical-memory-available-also-in-PBKDF-be.patch + - cryptsetup-Try-to-avoid-OOM-killer-on-low-memory-systems-withou.patch + - cryptsetup-Use-only-half-of-detected-free-memory-on-systems-wit.patch + +------------------------------------------------------------------- New: ---- cryptsetup-Check-for-physical-memory-available-also-in-PBKDF-be.patch cryptsetup-Try-to-avoid-OOM-killer-on-low-memory-systems-withou.patch cryptsetup-Use-only-half-of-detected-free-memory-on-systems-wit.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cryptsetup.spec ++++++ --- /var/tmp/diff_new_pack.vDuJll/_old 2023-07-15 23:14:29.879282224 +0200 +++ /var/tmp/diff_new_pack.vDuJll/_new 2023-07-15 23:14:29.883282248 +0200 @@ -29,6 +29,10 @@ Source1: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-%{version}.tar.sign Source2: baselibs.conf Source3: cryptsetup.keyring +#PATCH-FIX-UPSTREAM bsc#1211079 luksFormat: handle system with low memory and no swap space +Patch0: cryptsetup-Check-for-physical-memory-available-also-in-PBKDF-be.patch +Patch1: cryptsetup-Try-to-avoid-OOM-killer-on-low-memory-systems-withou.patch +Patch2: cryptsetup-Use-only-half-of-detected-free-memory-on-systems-wit.patch BuildRequires: device-mapper-devel BuildRequires: libjson-c-devel BuildRequires: libpwquality-devel ++++++ cryptsetup-Check-for-physical-memory-available-also-in-PBKDF-be.patch ++++++ >From 7893c33d71cde09e240234c484c6c468f22c2fe7 Mon Sep 17 00:00:00 2001 From: Milan Broz <gmazyl...@gmail.com> Date: Mon, 3 Apr 2023 13:31:16 +0200 Subject: [PATCH] Check for physical memory available also in PBKDF benchmark. --- lib/internal.h | 1 + lib/utils_benchmark.c | 9 +++++++++ lib/utils_pbkdf.c | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) Index: cryptsetup-2.6.1/lib/internal.h =================================================================== --- cryptsetup-2.6.1.orig/lib/internal.h +++ cryptsetup-2.6.1/lib/internal.h @@ -89,6 +89,7 @@ int crypt_benchmark_pbkdf_internal(struc 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; Index: cryptsetup-2.6.1/lib/utils_benchmark.c =================================================================== --- cryptsetup-2.6.1.orig/lib/utils_benchmark.c +++ cryptsetup-2.6.1/lib/utils_benchmark.c @@ -101,6 +101,7 @@ int crypt_benchmark_pbkdf(struct crypt_d { 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_d 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, Index: cryptsetup-2.6.1/lib/utils_pbkdf.c =================================================================== --- cryptsetup-2.6.1.orig/lib/utils_pbkdf.c +++ cryptsetup-2.6.1/lib/utils_pbkdf.c @@ -61,7 +61,7 @@ const struct crypt_pbkdf_type *crypt_get return NULL; } -static uint32_t adjusted_phys_memory(void) +uint32_t pbkdf_adjusted_phys_memory_kb(void) { uint64_t memory_kb = crypt_getphysmemory_kb(); @@ -249,7 +249,7 @@ int init_pbkdf_type(struct crypt_device } 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.", ++++++ cryptsetup-Try-to-avoid-OOM-killer-on-low-memory-systems-withou.patch ++++++ >From 899bad8c06957a94a198d1eaa293ed8db205f1de Mon Sep 17 00:00:00 2001 From: Milan Broz <gmazyl...@gmail.com> Date: Mon, 20 Feb 2023 16:45:36 +0100 Subject: [PATCH] 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. --- 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(-) Index: cryptsetup-2.6.1/lib/internal.h =================================================================== --- cryptsetup-2.6.1.orig/lib/internal.h +++ cryptsetup-2.6.1/lib/internal.h @@ -169,6 +169,8 @@ int crypt_uuid_cmp(const char *dm_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); Index: cryptsetup-2.6.1/lib/utils.c =================================================================== --- cryptsetup-2.6.1.orig/lib/utils.c +++ cryptsetup-2.6.1/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; Index: cryptsetup-2.6.1/lib/utils_pbkdf.c =================================================================== --- cryptsetup-2.6.1.orig/lib/utils_pbkdf.c +++ cryptsetup-2.6.1/lib/utils_pbkdf.c @@ -63,7 +63,7 @@ const struct crypt_pbkdf_type *crypt_get uint32_t pbkdf_adjusted_phys_memory_kb(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 @@ uint32_t pbkdf_adjusted_phys_memory_kb(v */ 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; } Index: cryptsetup-2.6.1/tests/api-test-2.c =================================================================== --- cryptsetup-2.6.1.orig/tests/api-test-2.c +++ cryptsetup-2.6.1/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); ++++++ cryptsetup-Use-only-half-of-detected-free-memory-on-systems-wit.patch ++++++ >From 6721d3a8b29b13fe88aeeaefe09d457e99d1c6fa Mon Sep 17 00:00:00 2001 From: Milan Broz <gmazyl...@gmail.com> Date: Mon, 17 Apr 2023 13:41:17 +0200 Subject: [PATCH] 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. --- lib/utils_pbkdf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) Index: cryptsetup-2.6.1/lib/utils_pbkdf.c =================================================================== --- cryptsetup-2.6.1.orig/lib/utils_pbkdf.c +++ cryptsetup-2.6.1/lib/utils_pbkdf.c @@ -76,10 +76,17 @@ uint32_t pbkdf_adjusted_phys_memory_kb(v 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; }