Commit 2dab2a53c9 for openssl.org
commit 2dab2a53c9234d9da3108fe4334d5e42bab9ed1d
Author: Bob Beck <beck@openssl.org>
Date: Tue Jun 9 15:18:56 2026 -0600
Fix BIO_write on file BIOs to report partial writes.
This makes it have the same behaviour as it does on all other
BIOs.
Due to a longstanding workaround that should no longer be needed
a partial write of the data (before a write error or end of file)
was reported as no data being written out.
Fixes: https://github.com/openssl/openssl/issues/31355
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Mon Jun 15 14:42:25 2026
(Merged from https://github.com/openssl/openssl/pull/31434)
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 76af9a460b..11e96a23d7 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -163,23 +163,16 @@ static int file_read(BIO *b, char *out, int outl)
static int file_write(BIO *b, const char *in, int inl)
{
- int ret = 0;
+ size_t ret = 0;
- if (b->init && (in != NULL)) {
+ if (inl < INT_MAX && inl >= 0 && b->init && (in != NULL)) {
if (b->flags & BIO_FLAGS_UPLINK_INTERNAL)
- ret = (int)UP_fwrite(in, inl, 1, b->ptr);
+ ret = (int)UP_fwrite(in, 1, (size_t)inl, b->ptr);
else
- ret = (int)fwrite(in, inl, 1, (FILE *)b->ptr);
- if (ret)
- ret = inl;
- /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
- /*
- * according to Tim Hudson <tjh@openssl.org>, the commented out
- * version above can cause 'inl' write calls under some stupid stdio
- * implementations (VMS)
- */
+ ret = fwrite(in, 1, (size_t)inl, (FILE *)b->ptr);
}
- return ret;
+
+ return (int)ret;
}
static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
diff --git a/test/bio_eof_test.c b/test/bio_eof_test.c
index 496331b351..da9b9d1f9e 100644
--- a/test/bio_eof_test.c
+++ b/test/bio_eof_test.c
@@ -223,10 +223,42 @@ static int new_style_read_ex(void)
return ok;
}
+static int test_short_file_write(void)
+{
+#if defined(OPENSSL_SYS_MACOSX)
+ int ok = 0;
+ char *data = "If you liked it then you should have put a test on it";
+ char buf[20];
+ FILE *stream = NULL;
+ BIO *bp = NULL;
+
+ stream = fmemopen(buf, 20, "wb");
+ if (!TEST_ptr(stream))
+ goto err;
+
+ bp = BIO_new_fp(stream, BIO_NOCLOSE);
+ if (!TEST_ptr(bp))
+ goto err;
+
+ if (!TEST_int_eq(BIO_write(bp, data, strlen(data)), 20))
+ goto err;
+
+ ok = 1;
+
+err:
+ fclose(stream);
+ BIO_free(bp);
+ return ok;
+#else
+ return TEST_skip("short file write test not supported on this platform");
+#endif
+}
+
int setup_tests(void)
{
ADD_TEST(old_style_read_without_eof_ctrl);
ADD_TEST(old_style_read_with_eof_ctrl);
ADD_TEST(new_style_read_ex);
+ ADD_TEST(test_short_file_write);
return 1;
}