Go to file
Domenico Cerasuolo 04fc781608 mm: fix zswap writeback race condition
The zswap writeback mechanism can cause a race condition resulting in
memory corruption, where a swapped out page gets swapped in with data that
was written to a different page.

The race unfolds like this:
1. a page with data A and swap offset X is stored in zswap
2. page A is removed off the LRU by zpool driver for writeback in
   zswap-shrink work, data for A is mapped by zpool driver
3. user space program faults and invalidates page entry A, offset X is
   considered free
4. kswapd stores page B at offset X in zswap (zswap could also be
   full, if so, page B would then be IOed to X, then skip step 5.)
5. entry A is replaced by B in tree->rbroot, this doesn't affect the
   local reference held by zswap-shrink work
6. zswap-shrink work writes back A at X, and frees zswap entry A
7. swapin of slot X brings A in memory instead of B

The fix:
Once the swap page cache has been allocated (case ZSWAP_SWAPCACHE_NEW),
zswap-shrink work just checks that the local zswap_entry reference is
still the same as the one in the tree.  If it's not the same it means that
it's either been invalidated or replaced, in both cases the writeback is
aborted because the local entry contains stale data.

Reproducer:
I originally found this by running `stress` overnight to validate my work
on the zswap writeback mechanism, it manifested after hours on my test
machine.  The key to make it happen is having zswap writebacks, so
whatever setup pumps /sys/kernel/debug/zswap/written_back_pages should do
the trick.

In order to reproduce this faster on a vm, I setup a system with ~100M of
available memory and a 500M swap file, then running `stress --vm 1
--vm-bytes 300000000 --vm-stride 4000` makes it happen in matter of tens
of minutes.  One can speed things up even more by swinging
/sys/module/zswap/parameters/max_pool_percent up and down between, say, 20
and 1; this makes it reproduce in tens of seconds.  It's crucial to set
`--vm-stride` to something other than 4096 otherwise `stress` won't
realize that memory has been corrupted because all pages would have the
same data.

Link: https://lkml.kernel.org/r/20230503151200.19707-1-cerasuolodomenico@gmail.com
Signed-off-by: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Chris Li (Google) <chrisl@kernel.org>
Cc: Dan Streetman <ddstreet@ieee.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Seth Jennings <sjenning@redhat.com>
Cc: Vitaly Wool <vitaly.wool@konsulko.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2023-05-17 15:24:33 -07:00
Documentation - mailbox api: allow direct registration to a channel 2023-05-07 10:17:33 -07:00
LICENSES LICENSES: Add the copyleft-next-0.3.1 license 2022-11-08 15:44:01 +01:00
arch s390: remove the unneeded select GCC12_NO_ARRAY_BOUNDS 2023-05-05 18:56:23 -07:00
block for-6.4/block-2023-05-06 2023-05-06 08:28:58 -07:00
certs KEYS: Add missing function documentation 2023-04-24 16:15:52 +03:00
crypto This push fixes the following problems: 2023-05-07 10:57:14 -07:00
drivers This push fixes the following problems: 2023-05-07 10:57:14 -07:00
fs 9 smb3 client fixes, mostly DFS or reconnect related 2023-05-07 10:46:21 -07:00
include mm: shrinkers: fix race condition on debugfs cleanup 2023-05-17 15:24:33 -07:00
init Objtool changes for v6.4: 2023-04-28 14:02:54 -07:00
io_uring for-6.4/io_uring-2023-05-07 2023-05-07 10:00:09 -07:00
ipc Merge branch 'work.namespace' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2023-02-24 19:20:07 -08:00
kernel Minor tracing updates: 2023-05-05 13:11:02 -07:00
lib maple_tree: make maple state reusable after mas_empty_area() 2023-05-17 15:24:32 -07:00
mm mm: fix zswap writeback race condition 2023-05-17 15:24:33 -07:00
net Including fixes from netfilter. 2023-05-05 19:12:01 -07:00
rust Rust changes for v6.4 2023-04-30 11:20:22 -07:00
samples LoongArch changes for v6.4 2023-05-04 12:40:16 -07:00
scripts Locking changes in v6.4: 2023-05-05 12:56:55 -07:00
security integrity-v6.4 2023-04-29 10:11:32 -07:00
sound sound fixes for 6.4-rc1 2023-05-06 08:07:11 -07:00
tools Disable building BPF based features by default for v6.4. 2023-05-07 11:32:18 -07:00
usr initramfs: Check negative timestamp to prevent broken cpio archive 2023-04-16 17:37:01 +09:00
virt s390: 2023-05-01 12:06:20 -07:00
.clang-format cxl for v6.4 2023-04-30 11:51:51 -07:00
.cocciconfig scripts: add Linux .cocciconfig for coccinelle 2016-07-22 12:13:39 +02:00
.get_maintainer.ignore get_maintainer: add Alan to .get_maintainer.ignore 2022-08-20 15:17:44 -07:00
.gitattributes .gitattributes: use 'dts' diff driver for *.dtso files 2023-02-26 15:28:23 +09:00
.gitignore linux-kselftest-kunit-6.4-rc1 2023-04-24 12:31:32 -07:00
.mailmap for-6.4/block-2023-05-06 2023-05-06 08:28:58 -07:00
.rustfmt.toml rust: add `.rustfmt.toml` 2022-09-28 09:02:20 +02:00
COPYING COPYING: state that all contributions really are covered by this file 2020-02-10 13:32:20 -08:00
CREDITS A handful of late-arriving documentation fixes, plus one Spanish 2023-05-05 13:16:42 -07:00
Kbuild Kbuild updates for v6.1 2022-10-10 12:00:45 -07:00
Kconfig kbuild: ensure full rebuild when the compiler is updated 2020-05-12 13:28:33 +09:00
MAINTAINERS Including fixes from netfilter. 2023-05-05 19:12:01 -07:00
Makefile Linux 6.4-rc1 2023-05-07 13:34:35 -07:00
README Drop all 00-INDEX files from Documentation/ 2018-09-09 15:08:58 -06:00

README

Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``.  The formatted documentation can also be read online at:

    https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.