Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package otpclient for openSUSE:Factory checked in at 2026-07-21 23:00:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/otpclient (Old) and /work/SRC/openSUSE:Factory/.otpclient.new.24530 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "otpclient" Tue Jul 21 23:00:41 2026 rev:52 rq:1366749 version:5.1.5 Changes: -------- --- /work/SRC/openSUSE:Factory/otpclient/otpclient.changes 2026-07-14 13:57:01.701595758 +0200 +++ /work/SRC/openSUSE:Factory/.otpclient.new.24530/otpclient.changes 2026-07-21 23:00:44.022398151 +0200 @@ -1,0 +2,17 @@ +Mon Jul 20 06:27:59 UTC 2026 - Paolo Stivanin <[email protected]> + +- Update to 5.1.5: + * FIX: a database stored on a filesystem without lock support + (the Flatpak document portal, and some NFS/SMB mounts) could + not be opened or created, failing with Failed to acquire + database lock: Function not implemented. Locking is now best- + effort, so the database opens normally on those filesystems, + while real locking is unchanged everywhere else (#466) + * FIX: the secure-memory pool reserved the whole RLIMIT_MEMLOCK + budget, so the GTK password entry could not lock its own buffer + and warned couldn't lock 16384 bytes of memory (gtk): Cannot + allocate memory, falling back to unlocked memory for the typed + password on every unlock. The pool now leaves headroom for it + (Debian #1141809) + +------------------------------------------------------------------- Old: ---- v5.1.4.tar.gz v5.1.4.tar.gz.asc New: ---- v5.1.5.tar.gz v5.1.5.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ otpclient.spec ++++++ --- /var/tmp/diff_new_pack.HKGgiS/_old 2026-07-21 23:00:45.642454026 +0200 +++ /var/tmp/diff_new_pack.HKGgiS/_new 2026-07-21 23:00:45.646454164 +0200 @@ -18,7 +18,7 @@ %define uclname OTPClient Name: otpclient -Version: 5.1.4 +Version: 5.1.5 Release: 0 Summary: Simple GTK+ client for managing TOTP and HOTP License: GPL-3.0-or-later ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.HKGgiS/_old 2026-07-21 23:00:45.710456371 +0200 +++ /var/tmp/diff_new_pack.HKGgiS/_new 2026-07-21 23:00:45.718456647 +0200 @@ -1,5 +1,5 @@ -mtime: 1783677767 -commit: 04838f01d636678220ee57cb23fc179016d264a8d2db38d44d75884e0a1996f0 +mtime: 1784528910 +commit: c5dfc727873cc35fbd92e5d70d25aa51991e7f0c910ac0fade8ac2b3e21ef9a1 url: https://src.opensuse.org/GNOME/otpclient revision: factory ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-07-20 08:28:30.000000000 +0200 @@ -0,0 +1,4 @@ +*.obscpio +*.osc +_build.* +.pbuild ++++++ v5.1.4.tar.gz -> v5.1.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/CMakeLists.txt new/OTPClient-5.1.5/CMakeLists.txt --- old/OTPClient-5.1.4/CMakeLists.txt 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/CMakeLists.txt 2026-07-16 17:45:17.000000000 +0200 @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(OTPClient VERSION "5.1.4" LANGUAGES "C") +project(OTPClient VERSION "5.1.5" LANGUAGES "C") include(GNUInstallDirs) include(CTest) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/data/com.github.paolostivanin.OTPClient.appdata.xml new/OTPClient-5.1.5/data/com.github.paolostivanin.OTPClient.appdata.xml --- old/OTPClient-5.1.4/data/com.github.paolostivanin.OTPClient.appdata.xml 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/data/com.github.paolostivanin.OTPClient.appdata.xml 2026-07-16 17:45:17.000000000 +0200 @@ -90,6 +90,15 @@ </content_rating> <releases> + <release version="5.1.5" date="2026-07-16"> + <description> + <p>Bug-fix release. A database stored on a filesystem that does not implement POSIX file locks, most notably the Flatpak XDG document-portal path (/run/user/UID/doc/) that the file chooser hands back, could not be opened or created and failed with "Failed to acquire database lock: Function not implemented"; the lock file added in 5.1.4 is now treated as best-effort. This release also stops the secure-memory pool from reserving the whole locked-memory budget, which had left the GTK password entry unable to lock its own buffer on every unlock.</p> + <ul> + <li>FIX: a database stored on a filesystem without lock support (the Flatpak document portal, and some NFS/SMB mounts) could not be opened or created, failing with "Failed to acquire database lock: Function not implemented". Locking is now best-effort so the database opens normally on those filesystems, while real locking is unchanged everywhere else (#466)</li> + <li>FIX: the secure-memory pool consumed the whole RLIMIT_MEMLOCK budget, so the GTK password entry could not lock its own buffer and warned "couldn't lock 16384 bytes of memory (gtk): Cannot allocate memory", falling back to unlocked memory for the typed password on every unlock; the pool now leaves headroom for it (Debian #1141809)</li> + </ul> + </description> + </release> <release version="5.1.4" date="2026-07-10"> <description> <p>Bug-fix release. Following the anonymous-token fix in 5.1.3, a database containing a token with an out-of-range digit count still refused to open, again locking users out of every other token. The load-time validator was stricter than the OTP engine and the app's own UI; the accepted ranges now match the engine (digits 4 to 10, period 1 to 120 seconds). Any token the engine still cannot use is set aside so the rest of the database opens, and is preserved for repair rather than dropped.</p> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/src/common/common.c new/OTPClient-5.1.5/src/common/common.c --- old/OTPClient-5.1.4/src/common/common.c 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/src/common/common.c 2026-07-16 17:45:17.000000000 +0200 @@ -18,6 +18,31 @@ gint32 +secmem_pool_from_limits (guint64 memlock_budget, + gint32 *memlock_value) +{ + // Enough room for our full default pool plus headroom for GTK/libadwaita's + // password-entry secure buffer: hand out the default and report OK. + if (memlock_budget >= (guint64) DEFAULT_MEMLOCK_VALUE + SECMEM_HEADROOM_VALUE) { + *memlock_value = DEFAULT_MEMLOCK_VALUE; + return MEMLOCK_OK; + } + + // Tighter budget: shrink our pool by SECMEM_HEADROOM_VALUE so the kernel still + // has locked-memory budget left for GTK's 16 KiB GtkPasswordEntryBuffer block + // (otherwise the app itself starves GTK and the unlock field can't be locked). + // If the budget is so small that reserving headroom would drop us below the + // floor, take what we can and let GTK warn rather than crippling ourselves. + if (memlock_budget > (guint64) SECMEM_HEADROOM_VALUE + MIN_SECMEM_POOL_VALUE) { + *memlock_value = (gint32) (memlock_budget - SECMEM_HEADROOM_VALUE); + } else { + *memlock_value = (gint32) memlock_budget; + } + return MEMLOCK_TOO_LOW; +} + + +gint32 set_memlock_value (gint32 *memlock_value) { struct rlimit r; @@ -26,14 +51,19 @@ return MEMLOCK_ERR; } - if (r.rlim_cur < DEFAULT_MEMLOCK_VALUE) { - // memlock is less than the default value, so we need to warn the user that there might not be enough secmem available. - *memlock_value = (gint32) r.rlim_cur; - return MEMLOCK_TOO_LOW; + // Best-effort: raise the soft limit toward the hard limit so both our libgcrypt + // pool and GTK/libadwaita's password-entry secure buffer can be locked. + // Unprivileged processes may raise the soft limit up to the hard limit; ignore + // failures and fall back to whatever the kernel currently reports. + if (r.rlim_cur != RLIM_INFINITY && r.rlim_cur < r.rlim_max) { + struct rlimit raised = r; + raised.rlim_cur = r.rlim_max; + if (setrlimit (RLIMIT_MEMLOCK, &raised) == 0) { + r = raised; + } } - *memlock_value = DEFAULT_MEMLOCK_VALUE; - return MEMLOCK_OK; + return secmem_pool_from_limits ((guint64) r.rlim_cur, memlock_value); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/src/common/common.h new/OTPClient-5.1.5/src/common/common.h --- old/OTPClient-5.1.4/src/common/common.h 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/src/common/common.h 2026-07-16 17:45:17.000000000 +0200 @@ -11,6 +11,8 @@ #define MEMLOCK_OK 2 #define MEMLOCK_TOO_LOW 3 #define DEFAULT_MEMLOCK_VALUE 67108864 // 64 MiB +#define SECMEM_HEADROOM_VALUE 1048576 // 1 MiB left unlocked below RLIMIT_MEMLOCK so GTK/libadwaita can still mlock the password-entry buffer +#define MIN_SECMEM_POOL_VALUE 1048576 // 1 MiB floor for our own pool when the limit is too low to reserve headroom #define SECMEM_SIZE_THRESHOLD_RATIO 0.80 #define SECMEM_REQUIRED_MULTIPLIER 3 @@ -43,6 +45,9 @@ gint32 set_memlock_value (gint32 *memlock_value); +gint32 secmem_pool_from_limits (guint64 memlock_budget, + gint32 *memlock_value); + gchar *init_libs (gint32 max_file_size); gint get_algo_int_from_str (const gchar *algo); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/src/common/db-common.c new/OTPClient-5.1.5/src/common/db-common.c --- old/OTPClient-5.1.4/src/common/db-common.c 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/src/common/db-common.c 2026-07-16 17:45:17.000000000 +0200 @@ -26,6 +26,7 @@ #ifdef OTPCLIENT_TESTING static gboolean test_fail_encrypt = FALSE; static gboolean test_fail_atomic_write = FALSE; +static gboolean test_unsupported_lock = FALSE; void db_test_set_fail_encrypt (gboolean fail) @@ -38,6 +39,12 @@ { test_fail_atomic_write = fail; } + +void +db_test_set_unsupported_lock (gboolean unsupported) +{ + test_unsupported_lock = unsupported; +} #endif static gint32 get_db_version (const gchar *db_path, @@ -299,6 +306,21 @@ } +/* Wrapper around flock() so tests can force the "filesystem does not support + * locking" path (see db_test_set_unsupported_lock). */ +static int +db_try_flock (int fd) +{ +#ifdef OTPCLIENT_TESTING + if (test_unsupported_lock) { + errno = ENOSYS; + return -1; + } +#endif + return flock (fd, LOCK_EX | LOCK_NB); +} + + static gboolean lock_db (const gchar *db_path, DbLock *lock, @@ -317,7 +339,24 @@ } gint64 deadline = g_get_monotonic_time () + (2 * G_USEC_PER_SEC); - while (flock (lock->fd, LOCK_EX | LOCK_NB) != 0) { + while (db_try_flock (lock->fd) != 0) { + if (errno == ENOSYS || errno == EOPNOTSUPP) { + /* Some filesystems do not implement POSIX locks and fail with + * ENOSYS/EOPNOTSUPP, notably the Flatpak XDG document-portal FUSE + * mount (/run/user/<uid>/doc/) and some NFS/SMB setups. The lock is + * a best-effort guard against a second OTPClient instance writing + * concurrently, not a correctness requirement, so continue without + * it rather than making the database impossible to open (issue #466). + * Leave lock->fd open; unlock_db () cleans it up. Warn once so we do + * not spam on every write. */ + static gboolean warned = FALSE; + if (!warned) { + g_warning ("Database lock not supported on this filesystem '%s'; " + "continuing without a lock: %s", lock->path, g_strerror (errno)); + warned = TRUE; + } + return TRUE; + } if (errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) { g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "Failed to acquire database lock '%s': %s", lock->path, g_strerror (errno)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/src/common/db-common.h new/OTPClient-5.1.5/src/common/db-common.h --- old/OTPClient-5.1.4/src/common/db-common.h 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/src/common/db-common.h 2026-07-16 17:45:17.000000000 +0200 @@ -189,6 +189,7 @@ #ifdef OTPCLIENT_TESTING void db_test_set_fail_encrypt (gboolean fail); void db_test_set_fail_atomic_write (gboolean fail); +void db_test_set_unsupported_lock (gboolean unsupported); #endif G_END_DECLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/tests/CMakeLists.txt new/OTPClient-5.1.5/tests/CMakeLists.txt --- old/OTPClient-5.1.4/tests/CMakeLists.txt 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/tests/CMakeLists.txt 2026-07-16 17:45:17.000000000 +0200 @@ -180,6 +180,20 @@ target_link_libraries(test_field_bounds_roundtrip ${COMMON_LIBS}) add_test(NAME field_bounds_roundtrip COMMAND test_field_bounds_roundtrip) +add_executable(test_memlock_sizing + test_memlock_sizing.c + ${PROJECT_SOURCE_DIR}/src/common/common.c + ${PROJECT_SOURCE_DIR}/src/common/file-size.c + ${PROJECT_SOURCE_DIR}/src/common/gquarks.c + ${PROJECT_SOURCE_DIR}/src/common/otp-validation.c +) +otpclient_apply_target_settings(test_memlock_sizing) +target_include_directories(test_memlock_sizing PRIVATE + ${PROJECT_SOURCE_DIR}/src/common +) +target_link_libraries(test_memlock_sizing ${COMMON_LIBS}) +add_test(NAME memlock_sizing COMMAND test_memlock_sizing) + if(BUILD_GUI) add_executable(test_otp_entry test_otp_entry.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/tests/README.md new/OTPClient-5.1.5/tests/README.md --- old/OTPClient-5.1.4/tests/README.md 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/tests/README.md 2026-07-16 17:45:17.000000000 +0200 @@ -83,3 +83,12 @@ and that a database file which does contain such a token still opens - the valid tokens load while the broken ones are set aside and preserved across a save/reload instead of bricking the whole database. + +**`test_memlock_sizing`** is the regression guard for the locked-memory +budgeting (Debian #1141809). It pins `secmem_pool_from_limits()`, the pure part +of `set_memlock_value()`, so that otpclient never sizes its libgcrypt secure +pool to the whole `RLIMIT_MEMLOCK` budget: it must always leave +`SECMEM_HEADROOM_VALUE` unlocked so GTK/libadwaita can still mlock its 16 KiB +password-entry buffer. It covers a generous budget (full 64 MiB pool), the +`RLIM_INFINITY` case (no overflow), the threshold and floor boundaries, and the +typical 8 MiB systemd limit that triggered the report. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/tests/test_db_transaction.c new/OTPClient-5.1.5/tests/test_db_transaction.c --- old/OTPClient-5.1.4/tests/test_db_transaction.c 2026-07-10 11:41:32.000000000 +0200 +++ new/OTPClient-5.1.5/tests/test_db_transaction.c 2026-07-16 17:45:17.000000000 +0200 @@ -204,6 +204,38 @@ cleanup_db_data (first, dir, path); } +static void +test_lock_unsupported_fallback (void) +{ + gchar *dir = NULL; + gchar *path = NULL; + DatabaseData *db_data = make_db_data (&dir, &path); + + /* Simulate a filesystem whose flock() fails with ENOSYS, e.g. the Flatpak + * document-portal FUSE mount (issue #466). The transaction must still + * succeed and write the database instead of aborting. */ + db_test_set_unsupported_lock (TRUE); + + /* The fallback warns exactly once per process; expect it on the first write. */ + g_test_expect_message (NULL, G_LOG_LEVEL_WARNING, "*lock not supported*"); + + GError *err = NULL; + g_assert_true (db_transaction (db_data, append_token_mutation, NULL, &err)); + g_assert_no_error (err); + g_test_assert_expected_messages (); + g_assert_true (g_file_test (path, G_FILE_TEST_EXISTS)); + g_assert_cmpint ((int) json_array_size (db_data->in_memory_json_data), ==, 2); + + /* A second write must also succeed and must NOT warn again (warn-once); + * an unexpected warning here would be fatal under the test harness. */ + g_assert_true (db_transaction (db_data, append_token_mutation, NULL, &err)); + g_assert_no_error (err); + g_assert_cmpint ((int) json_array_size (db_data->in_memory_json_data), ==, 3); + + db_test_set_unsupported_lock (FALSE); + cleanup_db_data (db_data, dir, path); +} + int main (int argc, char **argv) { @@ -216,6 +248,7 @@ g_test_add_func ("/db-transaction/password-change-failure", test_password_change_failure_restores_key); g_test_add_func ("/db-transaction/kdf-failure", test_kdf_failure_restores_params); g_test_add_func ("/db-transaction/stale-snapshot", test_stale_snapshot_rejected); + g_test_add_func ("/db-transaction/lock-unsupported-fallback", test_lock_unsupported_fallback); return g_test_run (); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-5.1.4/tests/test_memlock_sizing.c new/OTPClient-5.1.5/tests/test_memlock_sizing.c --- old/OTPClient-5.1.4/tests/test_memlock_sizing.c 1970-01-01 01:00:00.000000000 +0100 +++ new/OTPClient-5.1.5/tests/test_memlock_sizing.c 2026-07-16 17:45:17.000000000 +0200 @@ -0,0 +1,117 @@ +#include <glib.h> +#include "common.h" + +/* secmem_pool_from_limits() turns a locked-memory budget (RLIMIT_MEMLOCK) into + * the size of the libgcrypt secure pool otpclient asks for. The invariant that + * matters for bug #1141809 is that it must never claim the whole budget: it has + * to leave at least SECMEM_HEADROOM_VALUE unlocked so GTK/libadwaita can still + * mlock its 16 KiB GtkPasswordEntryBuffer block for the unlock field. Before the + * fix the app locked 100% of the budget and starved GTK, producing the reported + * "couldn't lock 16384 bytes of memory (gtk)" warning. */ + +#define MIB (1048576ULL) + +static void +test_budget_above_threshold_gets_default (void) +{ + /* Budget comfortably above default pool + headroom: full 64 MiB, OK. */ + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (128 * MIB, &pool), ==, MEMLOCK_OK); + g_assert_cmpint (pool, ==, DEFAULT_MEMLOCK_VALUE); +} + +static void +test_budget_exactly_at_threshold_gets_default (void) +{ + /* Exactly default + headroom is the smallest budget that still yields the + * full pool without eating into the reserve. */ + guint64 budget = (guint64) DEFAULT_MEMLOCK_VALUE + SECMEM_HEADROOM_VALUE; + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_OK); + g_assert_cmpint (pool, ==, DEFAULT_MEMLOCK_VALUE); +} + +static void +test_infinity_gets_default (void) +{ + /* RLIM_INFINITY reaches the helper as a very large value; it must not + * overflow the subtraction and must yield the default pool. */ + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (G_MAXUINT64, &pool), ==, MEMLOCK_OK); + g_assert_cmpint (pool, ==, DEFAULT_MEMLOCK_VALUE); +} + +static void +test_just_below_threshold_reserves_headroom (void) +{ + /* One byte below the threshold: we no longer get the full default, we get a + * pool shrunk by exactly the headroom, and the status drops to TOO_LOW. */ + guint64 budget = (guint64) DEFAULT_MEMLOCK_VALUE + SECMEM_HEADROOM_VALUE - 1; + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_TOO_LOW); + g_assert_cmpint (pool, ==, (gint32) (budget - SECMEM_HEADROOM_VALUE)); + g_assert_cmpuint (budget - (guint64) pool, >=, (guint64) SECMEM_HEADROOM_VALUE); +} + +static void +test_typical_8mib_leaves_headroom (void) +{ + /* The reporter's case: a small systemd DefaultLimitMEMLOCK. The pool must be + * shrunk so at least the headroom (>> GTK's 16 KiB) stays lockable. */ + guint64 budget = 8 * MIB; + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_TOO_LOW); + g_assert_cmpint (pool, ==, (gint32) (budget - SECMEM_HEADROOM_VALUE)); + g_assert_cmpuint (budget - (guint64) pool, >=, 16384); /* GTK's 16 KiB block fits */ +} + +static void +test_exactly_64mib_still_reserves (void) +{ + /* A limit of exactly the old default now reserves headroom instead of + * claiming all of it. The old code returned the full 64 MiB here, which is + * precisely what left GTK nothing to lock. */ + guint64 budget = DEFAULT_MEMLOCK_VALUE; + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_TOO_LOW); + g_assert_cmpint (pool, ==, (gint32) (budget - SECMEM_HEADROOM_VALUE)); +} + +static void +test_floor_budget_uses_all (void) +{ + /* When the budget is too small to carve out headroom without dropping below + * the floor, use what we have (a small locked pool beats none) and report + * TOO_LOW. GTK may still warn here, which is unavoidable at this limit. */ + guint64 budget = (guint64) SECMEM_HEADROOM_VALUE + MIN_SECMEM_POOL_VALUE; /* boundary, not > */ + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_TOO_LOW); + g_assert_cmpint (pool, ==, (gint32) budget); +} + +static void +test_just_above_floor_reserves (void) +{ + /* One byte above the floor boundary flips to the reserve branch. */ + guint64 budget = (guint64) SECMEM_HEADROOM_VALUE + MIN_SECMEM_POOL_VALUE + 1; + gint32 pool = -1; + g_assert_cmpint (secmem_pool_from_limits (budget, &pool), ==, MEMLOCK_TOO_LOW); + g_assert_cmpint (pool, ==, (gint32) (budget - SECMEM_HEADROOM_VALUE)); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/memlock-sizing/above-threshold-default", test_budget_above_threshold_gets_default); + g_test_add_func ("/memlock-sizing/at-threshold-default", test_budget_exactly_at_threshold_gets_default); + g_test_add_func ("/memlock-sizing/infinity-default", test_infinity_gets_default); + g_test_add_func ("/memlock-sizing/just-below-threshold", test_just_below_threshold_reserves_headroom); + g_test_add_func ("/memlock-sizing/typical-8mib", test_typical_8mib_leaves_headroom); + g_test_add_func ("/memlock-sizing/exactly-64mib", test_exactly_64mib_still_reserves); + g_test_add_func ("/memlock-sizing/floor-uses-all", test_floor_budget_uses_all); + g_test_add_func ("/memlock-sizing/just-above-floor", test_just_above_floor_reserves); + + return g_test_run (); +}
