# git rev-parse -q --verify b4b27b9eed8ebdbf9f3046197d29d733c8c944f3^{commit} b4b27b9eed8ebdbf9f3046197d29d733c8c944f3 already have revision, skipping fetch # git checkout -q -f -B kisskb b4b27b9eed8ebdbf9f3046197d29d733c8c944f3 # git clean -qxdf # < git log -1 # commit b4b27b9eed8ebdbf9f3046197d29d733c8c944f3 # Author: Linus Torvalds # Date: Sun Jun 27 13:32:54 2021 -0700 # # Revert "signal: Allow tasks to cache one sigqueue struct" # # This reverts commits 4bad58ebc8bc4f20d89cff95417c9b4674769709 (and # 399f8dd9a866e107639eabd3c1979cd526ca3a98, which tried to fix it). # # I do not believe these are correct, and I'm about to release 5.13, so am # reverting them out of an abundance of caution. # # The locking is odd, and appears broken. # # On the allocation side (in __sigqueue_alloc()), the locking is somewhat # straightforward: it depends on sighand->siglock. Since one caller # doesn't hold that lock, it further then tests 'sigqueue_flags' to avoid # the case with no locks held. # # On the freeing side (in sigqueue_cache_or_free()), there is no locking # at all, and the logic instead depends on 'current' being a single # thread, and not able to race with itself. # # To make things more exciting, there's also the data race between freeing # a signal and allocating one, which is handled by using WRITE_ONCE() and # READ_ONCE(), and being mutually exclusive wrt the initial state (ie # freeing will only free if the old state was NULL, while allocating will # obviously only use the value if it was non-NULL, so only one or the # other will actually act on the value). # # However, while the free->alloc paths do seem mutually exclusive thanks # to just the data value dependency, it's not clear what the memory # ordering constraints are on it. Could writes from the previous # allocation possibly be delayed and seen by the new allocation later, # causing logical inconsistencies? # # So it's all very exciting and unusual. # # And in particular, it seems that the freeing side is incorrect in # depending on "current" being single-threaded. Yes, 'current' is a # single thread, but in the presense of asynchronous events even a single # thread can have data races. # # And such asynchronous events can and do happen, with interrupts causing # signals to be flushed and thus free'd (for example - sending a # SIGCONT/SIGSTOP can happen from interrupt context, and can flush # previously queued process control signals). # # So regardless of all the other questions about the memory ordering and # locking for this new cached allocation, the sigqueue_cache_or_free() # assumptions seem to be fundamentally incorrect. # # It may be that people will show me the errors of my ways, and tell me # why this is all safe after all. We can reinstate it if so. But my # current belief is that the WRITE_ONCE() that sets the cached entry needs # to be a smp_store_release(), and the READ_ONCE() that finds a cached # entry needs to be a smp_load_acquire() to handle memory ordering # correctly. # # And the sequence in sigqueue_cache_or_free() would need to either use a # lock or at least be interrupt-safe some way (perhaps by using something # like the percpu 'cmpxchg': it doesn't need to be SMP-safe, but like the # percpu operations it needs to be interrupt-safe). # # Fixes: 399f8dd9a866 ("signal: Prevent sigqueue caching after task got released") # Fixes: 4bad58ebc8bc ("signal: Allow tasks to cache one sigqueue struct") # Cc: Thomas Gleixner # Cc: Peter Zijlstra # Cc: Oleg Nesterov # Cc: Christian Brauner # Signed-off-by: Linus Torvalds # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux-gcc --version # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux-ld --version # < git log --format=%s --max-count=1 b4b27b9eed8ebdbf9f3046197d29d733c8c944f3 # < make -s -j 32 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- allmodconfig # Added to kconfig CONFIG_BUILD_DOCSRC=n # Added to kconfig CONFIG_MODULE_SIG=n # Added to kconfig CONFIG_SAMPLES=n # < make -s -j 32 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- help # make -s -j 32 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- olddefconfig # make -s -j 32 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- /kisskb/src/arch/s390/kernel/traps.c: In function '__do_pgm_check': /kisskb/src/arch/s390/kernel/traps.c:359:1: warning: '__do_pgm_check' uses dynamic stack allocation } ^ /kisskb/src/arch/s390/kernel/syscall.c: In function '__do_syscall': /kisskb/src/arch/s390/kernel/syscall.c:169:1: warning: '__do_syscall' uses dynamic stack allocation } ^ /kisskb/src/drivers/input/joystick/analog.c:160:2: warning: #warning Precise timer not defined for this architecture. [-Wcpp] #warning Precise timer not defined for this architecture. ^~~~~~~ /kisskb/src/drivers/gpu/drm/rockchip/cdn-dp-core.c:1124:12: warning: 'cdn_dp_resume' defined but not used [-Wunused-function] static int cdn_dp_resume(struct device *dev) ^~~~~~~~~~~~~ In file included from /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:42: /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c: In function 'mvpp2_setup_bm_pool': /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2.h:844:2: warning: overflow in conversion from 'long unsigned int' to 'int' changes value from '18446744073709551584' to '-32' [-Woverflow] ((total_size) - MVPP2_SKB_HEADROOM - MVPP2_SKB_SHINFO_SIZE) ^ /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2.h:948:33: note: in expansion of macro 'MVPP2_RX_MAX_PKT_SIZE' #define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE) ^~~~~~~~~~~~~~~~~~~~~ /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:683:41: note: in expansion of macro 'MVPP2_BM_SHORT_PKT_SIZE' mvpp2_pools[MVPP2_BM_SHORT].pkt_size = MVPP2_BM_SHORT_PKT_SIZE; ^~~~~~~~~~~~~~~~~~~~~~~ Completed OK # rm -rf /kisskb/build/linus_s390-allmodconfig_s390x-gcc8 # Build took: 0:25:02.666691