]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
_umtx_op: fix a compat32 bug in UMTX_OP_NWAKE_PRIVATE
authorkevans <kevans@FreeBSD.org>
Tue, 17 Nov 2020 03:34:01 +0000 (03:34 +0000)
committerkevans <kevans@FreeBSD.org>
Tue, 17 Nov 2020 03:34:01 +0000 (03:34 +0000)
commite6bc7219d62dcbff0fff5070fd10e331f58330da
treeca12a08b2a00e82f55d218cc634720aaa2475fad
parent790b887b590b247429f8f07b300e97bd58c50d5f
_umtx_op: fix a compat32 bug in UMTX_OP_NWAKE_PRIVATE

Specifically, if we're waking up some value n > BATCH_SIZE, then the
copyin(9) is wrong on the second iteration due to upp being the wrong type.
upp is currently a uint32_t**, so upp + pos advances it by twice as many
elements as it should (host pointer size vs. compat32 pointer size).

Fix it by just making upp a uint32_t*; it's still technically a double
pointer, but the distinction doesn't matter all that much here since we're
just doing arithmetic on it.

Add a test case that demonstrates the problem, placed with the libthr tests
since one messing with _umtx_op should be running these tests. Running under
compat32, the new test case will hang as threads after the first 128 get
missed in the wake. it's not immediately clear how to hit it in practice,
since pthread_cond_broadcast() uses a smaller (sleepq batch?) size observed
to be around ~50 -- I did not spend much time digging into it.

The uintptr_t change makes no functional difference, but i've tossed it in
since it's more accurate (semantically).

Reported by: Andrew Gierth (andrew_tao173.riddles.org.uk, inspection)
Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D27231
lib/libthr/tests/Makefile
lib/libthr/tests/umtx_op_test.c [new file with mode: 0644]
sys/kern/kern_umtx.c