Reproducer for luksSuspend-sync-suspend race condition
The Linux Kernel always
sync()s before suspending to memory. That leads to race conditions if we
luksSuspend beforehands: The block device is already luksSuspended and therefore doesn't accept to flush further pending read/write operations.
The solution would be to make the final
sync() in the kernel suspend code optional. There's already a build-time flag for this. We need a run-time flag.
This is a simple C program to enforce a race condition when using
cryptroot-suspend.c for suspending.
- Debian Sid/Unstable system with Linux Kernel 5.2.0-3 (5.2.17-1)
- Debian Cryptsetup with cryptroot-suspend implementation
Compilation (as it would be done in Debian packaging process)
x86_64-linux-gnu-gcc -o suspend-race-reproducer suspend-race-reproducer.c -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wl,-z,now --pedantic
./suspend-race-reproducer /teststate /testlog /lib/cryptsetup/scripts/cryptroot-suspend-wrapper
Suspend state must not be reached if the reproducer works.
With a patched kernel (that doesn't
sync() before suspend), the reproducer doesn't work anymore and suspend state should be reached despite
suspend-race-reproducer is running. After resuming, you can kill the reproducer with