qemu-cr16/io
Peter Xu 7e0c22d585 io/crypto: Move tls premature termination handling into QIO layer
QCryptoTLSSession allows TLS premature termination in two cases, one of the
case is when the channel shutdown() is invoked on READ side.

It's possible the shutdown() happened after the read thread blocked at
gnutls_record_recv().  In this case, we should allow the premature
termination to happen.

The problem is by the time qcrypto_tls_session_read() was invoked,
tioc->shutdown may not have been set, so this may instead be treated as an
error if there is concurrent shutdown() calls.

To allow the flag to reflect the latest status of tioc->shutdown, move the
check upper into the QIOChannel level, so as to read the flag only after
QEMU gets an GNUTLS_E_PREMATURE_TERMINATION.

When at it, introduce qio_channel_tls_allow_premature_termination() helper
to make the condition checks easier to read.  When doing so, change the
qatomic_load_acquire() to qatomic_read(): here we don't need any ordering
of memory accesses, but reading a flag.  qatomic_read() would suffice
because it guarantees fetching from memory.  Nothing else we should need to
order on memory access.

This patch will fix a qemu qtest warning when running the preempt tls test,
reporting premature termination:

QTEST_QEMU_BINARY=./qemu-system-x86_64 ./tests/qtest/migration-test --full -r /x86_64/migration/postcopy/preempt/tls/psk
...
qemu-kvm: Cannot read from TLS channel: The TLS connection was non-properly terminated.
...

In this specific case, the error was set by postcopy_preempt_thread, which
normally will be concurrently shutdown()ed by the main thread.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Juraj Marcin <jmarcin@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20250918203937.200833-2-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
2025-10-03 09:48:02 -04:00
..
channel-buffer.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
channel-command.c treewide: use qemu_set_blocking instead of g_unix_set_fd_nonblocking 2025-09-19 12:46:07 +01:00
channel-file.c treewide: use qemu_set_blocking instead of g_unix_set_fd_nonblocking 2025-09-19 12:46:07 +01:00
channel-null.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
channel-socket.c error: Kill @error_warn 2025-10-01 08:33:24 +02:00
channel-tls.c io/crypto: Move tls premature termination handling into QIO layer 2025-10-03 09:48:02 -04:00
channel-util.c io: follow coroutine AioContext in qio_channel_yield() 2023-09-07 20:32:11 -05:00
channel-watch.c error: Kill @error_warn 2025-10-01 08:33:24 +02:00
channel-websock.c treewide: handle result of qio_channel_set_blocking() 2025-09-19 12:46:07 +01:00
channel.c treewide: handle result of qio_channel_set_blocking() 2025-09-19 12:46:07 +01:00
dns-resolver.c io: Fix partial struct copy in qio_dns_resolver_lookup_sync_inet() 2025-05-22 11:24:41 +01:00
meson.build Revert "meson: Propagate gnutls dependency" 2024-07-03 18:41:26 +02:00
net-listener.c io: Stop appending -listen to net listeners 2023-11-07 14:54:56 +00:00
task.c io: Fix Lesser GPL version number 2020-10-29 09:57:37 +00:00
trace-events io: tls: Add qio_channel_tls_bye 2025-02-14 15:19:03 -03:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00