# git rev-parse -q --verify 10d20bd25e06b220b1d816228b036e367215dc60^{commit} 10d20bd25e06b220b1d816228b036e367215dc60 already have revision, skipping fetch # git checkout -q -f -B kisskb 10d20bd25e06b220b1d816228b036e367215dc60 # git clean -qxdf # git log -1 commit 10d20bd25e06b220b1d816228b036e367215dc60 Author: Linus Torvalds Date: Mon Dec 5 12:10:29 2016 -0800 shmem: fix shm fallocate() list corruption The shmem hole punching with fallocate(FALLOC_FL_PUNCH_HOLE) does not want to race with generating new pages by faulting them in. However, the wait-queue used to delay the page faulting has a serious problem: the wait queue head (in shmem_fallocate()) is allocated on the stack, and the code expects that "wake_up_all()" will make sure that all the queue entries are gone before the stack frame is de-allocated. And that is not at all necessarily the case. Yes, a normal wake-up sequence will remove the wait-queue entry that caused the wakeup (see "autoremove_wake_function()"), but the key wording there is "that caused the wakeup". When there are multiple possible wakeup sources, the wait queue entry may well stay around. And _particularly_ in a page fault path, we may be faulting in new pages from user space while we also have other things going on, and there may well be other pending wakeups. So despite the "wake_up_all()", it's not at all guaranteed that all list entries are removed from the wait queue head on the stack. Fix this by introducing a new wakeup function that removes the list entry unconditionally, even if the target process had already woken up for other reasons. Use that "synchronous" function to set up the waiters in shmem_fault(). This problem has never been seen in the wild afaik, but Dave Jones has reported it on and off while running trinity. We thought we fixed the stack corruption with the blk-mq rq_list locking fix (commit 7fe311302f7d: "blk-mq: update hardware and software queues for sleeping alloc"), but it turns out there was _another_ stack corruptor hiding in the trinity runs. Vegard Nossum (also running trinity) was able to trigger this one fairly consistently, and made us look once again at the shmem code due to the faults often being in that area. Reported-and-tested-by: Vegard Nossum . Reported-by: Dave Jones Signed-off-by: Linus Torvalds # < /opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux-gcc --version # < git log --format=%s --max-count=1 10d20bd25e06b220b1d816228b036e367215dc60 # < make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 defconfig kernel/time/Kconfig:155:warning: range is invalid # make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 make[1]: Entering directory '/home/kisskb/slave/build/linus_um-defconfig_um-x86_64' GEN ./Makefile scripts/kconfig/conf --silentoldconfig arch/x86/um/Kconfig kernel/time/Kconfig:155:warning: range is invalid CHK include/generated/uapi/linux/version.h UPD include/generated/uapi/linux/version.h HOSTCC scripts/basic/bin2c WRAP arch/um/include/generated/asm/barrier.h WRAP arch/um/include/generated/asm/bug.h WRAP arch/um/include/generated/asm/clkdev.h WRAP arch/um/include/generated/asm/current.h WRAP arch/um/include/generated/asm/cputime.h WRAP arch/um/include/generated/asm/emergency-restart.h WRAP arch/um/include/generated/asm/delay.h WRAP arch/um/include/generated/asm/device.h WRAP arch/um/include/generated/asm/exec.h WRAP arch/um/include/generated/asm/ftrace.h WRAP arch/um/include/generated/asm/futex.h WRAP arch/um/include/generated/asm/hardirq.h WRAP arch/um/include/generated/asm/hw_irq.h WRAP arch/um/include/generated/asm/io.h WRAP arch/um/include/generated/asm/irq_regs.h WRAP arch/um/include/generated/asm/irq_work.h WRAP arch/um/include/generated/asm/kdebug.h WRAP arch/um/include/generated/asm/mcs_spinlock.h WRAP arch/um/include/generated/asm/mm-arch-hooks.h WRAP arch/um/include/generated/asm/mutex.h WRAP arch/um/include/generated/asm/param.h WRAP arch/um/include/generated/asm/pci.h WRAP arch/um/include/generated/asm/percpu.h WRAP arch/um/include/generated/asm/preempt.h WRAP arch/um/include/generated/asm/switch_to.h WRAP arch/um/include/generated/asm/topology.h WRAP arch/um/include/generated/asm/trace_clock.h WRAP arch/um/include/generated/asm/word-at-a-time.h WRAP arch/um/include/generated/asm/xor.h CHK include/config/kernel.release GEN ./Makefile HOSTCC scripts/kallsyms CC scripts/mod/empty.o HOSTCC scripts/mod/mk_elfconfig CC scripts/mod/devicetable-offsets.s UPD include/config/kernel.release MKELF scripts/mod/elfconfig.h HOSTCC scripts/mod/modpost.o HOSTCC scripts/mod/sumversion.o GEN scripts/mod/devicetable-offsets.h HOSTCC scripts/mod/file2alias.o SYSTBL arch/x86/entry/syscalls/../../include/generated/asm/syscalls_32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/asm/unistd_32_ia32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/asm/unistd_64_x32.h SYSTBL arch/x86/entry/syscalls/../../include/generated/asm/syscalls_64.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_64.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_x32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_32.h HOSTLD scripts/mod/modpost Using /home/kisskb/slave/src as source for kernel CHK include/generated/utsrelease.h UPD include/generated/utsrelease.h HOSTCC scripts/unifdef CC arch/x86/um/user-offsets.s In file included from /usr/include/features.h:374:0, from /usr/include/stdio.h:27, from /home/kisskb/slave/src/arch/x86/um/user-offsets.c:1: /opt/cross/gcc-4.6.3-nolibc/x86_64-linux/lib/gcc/x86_64-linux/4.6.3/../../../../x86_64-linux/include/sys/cdefs.h:385:27: fatal error: bits/wordsize.h: No such file or directory compilation terminated. /home/kisskb/slave/src/scripts/Makefile.build:154: recipe for target 'arch/x86/um/user-offsets.s' failed make[2]: *** [arch/x86/um/user-offsets.s] Error 1 arch/um/Makefile:150: recipe for target 'arch/x86/um/user-offsets.s' failed make[1]: *** [arch/x86/um/user-offsets.s] Error 2 make[1]: Leaving directory '/home/kisskb/slave/build/linus_um-defconfig_um-x86_64' Makefile:150: recipe for target 'sub-make' failed make: *** [sub-make] Error 2 Command 'make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 ' returned non-zero exit status 2 # rm -rf /home/kisskb/slave/build/linus_um-defconfig_um-x86_64 # Build took: 0:00:05.316034