Contact Details (e.g. Tox ID or email)
No response
qTox Version
master @ 2026-08-20
Commit Hash
2de5186
Toxcore Version
0.2.23
Qt Version
6.10.2
Steps to reproduce
- Start two instances (or one instance plus a toxcore harness) and get an A/V call going.
- The audio frames go out through
CoreAV::sendCallAudio on the OpenAL thread, the video through sendCallVideo on the camera thread. Neither takes coreLoopLock (coreav.cpp:359 and :415)
- Meanwhile
Core::process runs tox_iterate on the core thread (core.cpp:264)
experimental_thread_safety is not enabled, so tox_lock/tox_unlock are no-ops
- That puts three threads in
increment_nonce (crypto_core.c:384-390) on the same connection, the audio and video sides holding different mutexes. The increment isn't atomic, updates get lost, and the same nonce gets reused.
Observed Behavior
TSan reports the race: 37 hits on increment_nonce (crypto_core.c:387/388). I instrumented the send path to log every nonce. A 20 second run, 262139 packets: 353 duplicate nonce groups, 871 packets sent under a reused nonce, 518 nonces used twice. One nonce encrypted 5 packets. XORing two captured ciphertexts under the same nonce gives C1 xor C2 = P1 xor P2, and the recovered plaintext matches the real one. I also have a pcap showing both datagrams carrying the same nonce suffix, happy to attach it if useful.
Expected Behavior
No nonce reuse. With experimental_thread_safety enabled the same harness sent 245781 packets with 0 duplicates.
Reproducibility
Always
Operating System
Linux
Operating System version/distro/name/etc.
No response
Relevant log output
WARNING: ThreadSanitizer: data race
#0 increment_nonce crypto_core.c:387
#1 send_data_packet net_crypto.c:1110
#2 send_lossy_cryptpacket net_crypto.c:2873
#3 m_send_custom_lossy_packet Messenger.c:1890
#4 tox_friend_send_lossy_packet tox.c:2859
Contact Details (e.g. Tox ID or email)
No response
qTox Version
master @ 2026-08-20
Commit Hash
2de5186
Toxcore Version
0.2.23
Qt Version
6.10.2
Steps to reproduce
CoreAV::sendCallAudioon the OpenAL thread, the video throughsendCallVideoon the camera thread. Neither takescoreLoopLock(coreav.cpp:359and:415)Core::processrunstox_iterateon the core thread (core.cpp:264)experimental_thread_safetyis not enabled, so tox_lock/tox_unlock are no-opsincrement_nonce(crypto_core.c:384-390) on the same connection, the audio and video sides holding different mutexes. The increment isn't atomic, updates get lost, and the same nonce gets reused.Observed Behavior
TSan reports the race: 37 hits on
increment_nonce(crypto_core.c:387/388). I instrumented the send path to log every nonce. A 20 second run, 262139 packets: 353 duplicate nonce groups, 871 packets sent under a reused nonce, 518 nonces used twice. One nonce encrypted 5 packets. XORing two captured ciphertexts under the same nonce givesC1 xor C2 = P1 xor P2, and the recovered plaintext matches the real one. I also have a pcap showing both datagrams carrying the same nonce suffix, happy to attach it if useful.Expected Behavior
No nonce reuse. With
experimental_thread_safetyenabled the same harness sent 245781 packets with 0 duplicates.Reproducibility
Always
Operating System
Linux
Operating System version/distro/name/etc.
No response
Relevant log output