Switch some BIO_write calls to BIO_write_ex

Bug: 42290376
Change-Id: I435b8d80455e3a10d53242fc53b45e9ca4d37f6a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/96110
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bio/bio.cc b/crypto/bio/bio.cc
index 17b068c..e0e55da 100644
--- a/crypto/bio/bio.cc
+++ b/crypto/bio/bio.cc
@@ -25,6 +25,7 @@
 #include <openssl/asn1.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
+#include <openssl/span.h>
 
 #include "../internal.h"
 #include "../mem_internal.h"
@@ -173,14 +174,13 @@
 }
 
 int BIO_write_all(BIO *bio, const void *data, size_t len) {
-  const uint8_t *data_u8 = reinterpret_cast<const uint8_t *>(data);
-  while (len > 0) {
-    int ret = BIO_write(bio, data_u8, len > INT_MAX ? INT_MAX : (int)len);
-    if (ret <= 0) {
+  auto span = Span(reinterpret_cast<const uint8_t *>(data), len);
+  while (!span.empty()) {
+    size_t written;
+    if (!BIO_write_ex(bio, span.data(), span.size(), &written)) {
       return 0;
     }
-    data_u8 += ret;
-    len -= ret;
+    span = span.subspan(written);
   }
   return 1;
 }
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc
index d3ad437..7b63d43 100644
--- a/ssl/d1_both.cc
+++ b/ssl/d1_both.cc
@@ -913,13 +913,13 @@
     }
 
     if (packet_len != 0) {
-      int bio_ret = BIO_write(ssl->wbio.get(), packet.data(), packet_len);
-      if (bio_ret <= 0) {
+      if (!BIO_write_ex(ssl->wbio.get(), packet.data(), packet_len,
+                        /*out_written=*/nullptr)) {
         // Retry this packet the next time around.
         ssl->d1->outgoing_written = old_written;
         ssl->d1->outgoing_offset = old_offset;
         ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
-        return bio_ret;
+        return -1;
       }
     }
   }
@@ -1007,11 +1007,10 @@
 
   ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_ACK, CBBAsSpan(&cbb));
 
-  int bio_ret =
-      BIO_write(ssl->wbio.get(), record, static_cast<int>(record_len));
-  if (bio_ret <= 0) {
+  if (!BIO_write_ex(ssl->wbio.get(), record, record_len,
+                    /*out_written=*/nullptr)) {
     ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
-    return bio_ret;
+    return -1;
   }
 
   ssl->d1->pending_flush = true;
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc
index 3ed6c7c..142a879 100644
--- a/ssl/s3_both.cc
+++ b/ssl/s3_both.cc
@@ -210,8 +210,7 @@
     return -1;
   }
 
-  static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits");
-  if (ssl->s3->pending_flight->length > INT_MAX) {
+  if (ssl->s3->pending_flight->length > UINT32_MAX) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
     return -1;
   }
@@ -233,16 +232,17 @@
 
   // Write the pending flight.
   while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) {
-    int ret = BIO_write(
-        ssl->wbio.get(),
-        ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
-        ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset);
-    if (ret <= 0) {
+    size_t written;
+    if (!BIO_write_ex(
+            ssl->wbio.get(),
+            ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
+            ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset,
+            &written)) {
       ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
-      return ret;
+      return -1;
     }
 
-    ssl->s3->pending_flight_offset += ret;
+    ssl->s3->pending_flight_offset += static_cast<uint32_t>(written);
   }
 
   if (BIO_flush(ssl->wbio.get()) <= 0) {
diff --git a/ssl/ssl_buffer.cc b/ssl/ssl_buffer.cc
index c6beb31..bb39afa 100644
--- a/ssl/ssl_buffer.cc
+++ b/ssl/ssl_buffer.cc
@@ -257,14 +257,13 @@
 
 static int tls_write_buffer_flush(SSL *ssl) {
   SSLBuffer *buf = &ssl->s3->write_buffer;
-
   while (!buf->empty()) {
-    int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
-    if (ret <= 0) {
+    size_t written;
+    if (!BIO_write_ex(ssl->wbio.get(), buf->data(), buf->size(), &written)) {
       ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
-      return ret;
+      return -1;
     }
-    buf->Consume(static_cast<size_t>(ret));
+    buf->Consume(written);
   }
   buf->Clear();
   return 1;
@@ -276,14 +275,14 @@
     return 1;
   }
 
-  int ret = BIO_write(ssl->wbio.get(), buf->data(), buf->size());
-  if (ret <= 0) {
+  if (!BIO_write_ex(ssl->wbio.get(), buf->data(), buf->size(),
+                    /*out_written=*/nullptr)) {
     ssl->s3->rwstate = SSL_ERROR_WANT_WRITE;
     // If the write failed, drop the write buffer anyway. Datagram transports
     // can't write half a packet, so the caller is expected to retry from the
     // top.
     buf->Clear();
-    return ret;
+    return -1;
   }
   buf->Clear();
   return 1;