]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix SSL_write_[ex|ex2] on blocking quic streams
authorNeil Horman <nhorman@openssl.org>
Tue, 19 Nov 2024 16:58:30 +0000 (11:58 -0500)
committerTomas Mraz <tomas@openssl.org>
Thu, 21 Nov 2024 15:04:20 +0000 (16:04 +0100)
When writing to a blocking quic stream, we sometimes get duplicate
transmitted data.  This occurs when a call to quic_write_blocking has to
wait for space to become available in the ring buffer.  When we do a
wait, the call sets *written to the value returned in args.total_written
as filled out by the calls to block_until_pred->quic_write_again.
However, the value there is based on the amount we requested, which is
only the remaining data that we didn't append in xso_sstream_write.  So
if we call quic_write_blocking with a buffer of length X, and initially
append Y bytes, and write the remainig X-Y bytes via a block_until_pred
call, then *written will return with the value X-Y, even though we wrote
the full X bytes to the ring buffer.

Fix it by recording the initial amount appended into *written, and then
add the args.total_written value if we have to wait on more space

Fixes openssl/project#924

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26023)

(cherry picked from commit 2de7e1d69851a363cadd9d6bdd95302b89a4383b)

ssl/quic/quic_impl.c

index 1dacce8bcc2916975e9bb431f709538b1ec7d47b..240eaab72b5703f5d508213d22874c5384325591 100644 (file)
@@ -2317,9 +2317,13 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,
 
     quic_post_write(xso, actual_written > 0, actual_written == len, flags, 1);
 
+    /*
+     * Record however much data we wrote
+     */
+    *written = actual_written;
+
     if (actual_written == len) {
         /* Managed to append everything on the first try. */
-        *written = actual_written;
         return 1;
     }
 
@@ -2343,7 +2347,14 @@ static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len,
             return QUIC_RAISE_NON_NORMAL_ERROR(ctx, args.err, NULL);
     }
 
-    *written = args.total_written;
+    /*
+     * When waiting on extra buffer space to be available, args.total_written
+     * holds the amount of remaining data we requested to write, which will be
+     * something less than the len parameter passed in, however much we wrote
+     * here, add it to the value that we wrote when we initially called
+     * xso_sstream_append
+     */
+    *written += args.total_written;
     return 1;
 }