From e99bcaff789941a94416996daeb423df295d5443 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 11 Mar 2023 07:32:46 +0000 Subject: [PATCH] Fix desychronisation with kTLS: https://gitlab.com/gnutls/gnutls/-/issues/1470 --- ...rn-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch | 52 +++++++++++++++++++ gnutls.spec | 4 ++ 2 files changed, 56 insertions(+) create mode 100644 gnutls-3.8.0-ktls-Do-not-return-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch diff --git a/gnutls-3.8.0-ktls-Do-not-return-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch b/gnutls-3.8.0-ktls-Do-not-return-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch new file mode 100644 index 0000000..0390da3 --- /dev/null +++ b/gnutls-3.8.0-ktls-Do-not-return-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch @@ -0,0 +1,52 @@ +From 21c386860f1973344872eec4e4dd68644b1b48aa Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 10 Mar 2023 11:15:19 +0000 +Subject: [PATCH] ktls: Do not return GNUTLS_E_INTERRUPTED/AGAIN from short + writes + +If sendmsg returns a short write, we end up going around the loop with +data_to_send being smaller. However if sendmsg then returns -EAGAIN +or -EINTR then we return an error. But we have "forgotten" that we +already sent some data. + +This causes the caller to retry gnutls_record_send with the full +buffer (ie. with a buffer that has already been partially sent), +causing desynchronization. + +Instead check if we sent some data in this case and return the number +of bytes sent. + +Fixes: https://gitlab.com/gnutls/gnutls/-/issues/1470 +Thanks: Dan Berrange for suggesting a fix +Signed-off-by: Richard W.M. Jones +--- + lib/system/ktls.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/lib/system/ktls.c b/lib/system/ktls.c +index fd57a9c30..bb59fab7c 100644 +--- a/lib/system/ktls.c ++++ b/lib/system/ktls.c +@@ -604,9 +604,17 @@ int _gnutls_ktls_send_control_msg(gnutls_session_t session, + if (ret == -1) { + switch (errno) { + case EINTR: +- return GNUTLS_E_INTERRUPTED; ++ if (data_to_send < data_size) { ++ return data_size - data_to_send; ++ } else { ++ return GNUTLS_E_INTERRUPTED; ++ } + case EAGAIN: +- return GNUTLS_E_AGAIN; ++ if (data_to_send < data_size) { ++ return data_size - data_to_send; ++ } else { ++ return GNUTLS_E_AGAIN; ++ } + default: + return GNUTLS_E_PUSH_ERROR; + } +-- +2.39.2 + diff --git a/gnutls.spec b/gnutls.spec index 23c169a..d43bcec 100644 --- a/gnutls.spec +++ b/gnutls.spec @@ -29,6 +29,10 @@ Patch: gnutls-3.7.8-ktls_disable_keyupdate_test.patch # follow https://gitlab.com/gnutls/gnutls/-/issues/1443 Patch: gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch +# Fix desychronisation with kTLS: +# https://gitlab.com/gnutls/gnutls/-/issues/1470 +Patch: gnutls-3.8.0-ktls-Do-not-return-GNUTLS_E_INTERRUPTED-AGAIN-from-s.patch + %bcond_without bootstrap %bcond_without dane %bcond_without fips