Fossil SCM

Alternative to [b890451cfb], [b70557f690] and [acffc8f785] to fix the SSL_read() loops on Windows. Pending tests on non-Windows platforms.

florian 2022-01-26 07:41 trunk
Commit 95256636e4682bf1c86bce75eb089e5de00c4b52948c65c0489254ec5b9f700a
+8
--- src/blob.c
+++ src/blob.c
@@ -983,17 +983,25 @@
983983
blob_zero(pBlob);
984984
if( nToRead<0 ){
985985
char zBuf[10000];
986986
while( !cgi_feof() ){
987987
n = cgi_fread(zBuf, sizeof(zBuf));
988
+ if( n==(size_t)-1 ){
989
+ blob_zero(pBlob);
990
+ return -1;
991
+ }
988992
if( n>0 ){
989993
blob_append(pBlob, zBuf, n);
990994
}
991995
}
992996
}else{
993997
blob_resize(pBlob, nToRead);
994998
n = cgi_fread(blob_buffer(pBlob), nToRead);
999
+ if( n==(size_t)-1 ){
1000
+ blob_zero(pBlob);
1001
+ return -1;
1002
+ }
9951003
blob_resize(pBlob, n);
9961004
}
9971005
return blob_size(pBlob);
9981006
}
9991007
10001008
--- src/blob.c
+++ src/blob.c
@@ -983,17 +983,25 @@
983 blob_zero(pBlob);
984 if( nToRead<0 ){
985 char zBuf[10000];
986 while( !cgi_feof() ){
987 n = cgi_fread(zBuf, sizeof(zBuf));
 
 
 
 
988 if( n>0 ){
989 blob_append(pBlob, zBuf, n);
990 }
991 }
992 }else{
993 blob_resize(pBlob, nToRead);
994 n = cgi_fread(blob_buffer(pBlob), nToRead);
 
 
 
 
995 blob_resize(pBlob, n);
996 }
997 return blob_size(pBlob);
998 }
999
1000
--- src/blob.c
+++ src/blob.c
@@ -983,17 +983,25 @@
983 blob_zero(pBlob);
984 if( nToRead<0 ){
985 char zBuf[10000];
986 while( !cgi_feof() ){
987 n = cgi_fread(zBuf, sizeof(zBuf));
988 if( n==(size_t)-1 ){
989 blob_zero(pBlob);
990 return -1;
991 }
992 if( n>0 ){
993 blob_append(pBlob, zBuf, n);
994 }
995 }
996 }else{
997 blob_resize(pBlob, nToRead);
998 n = cgi_fread(blob_buffer(pBlob), nToRead);
999 if( n==(size_t)-1 ){
1000 blob_zero(pBlob);
1001 return -1;
1002 }
1003 blob_resize(pBlob, n);
1004 }
1005 return blob_size(pBlob);
1006 }
1007
1008
+17 -9
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,10 +811,11 @@
811811
}
812812
813813
/*
814814
** Read cleartext bytes that have been received from the client and
815815
** decrypted by the SSL server codec.
816
+** Return (size_t)-1 on error.
816817
*/
817818
size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
818819
int n;
819820
size_t rc = 0;
820821
SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -821,21 +822,28 @@
821822
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822823
else if( BIO_eof(pServer->bio) ) return 0;
823824
while( nBuf!=rc ){
824825
n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825826
if( n<=0 ){
826
- break;
827
+ int error = SSL_get_error(pServer->ssl,n);
828
+ switch( error ){
829
+ case SSL_ERROR_NONE:
830
+ case SSL_ERROR_ZERO_RETURN:
831
+ /* Not all errors relevant with SSL_MODE_AUTO_RETRY. */
832
+ case SSL_ERROR_WANT_READ:
833
+ case SSL_ERROR_WANT_WRITE:
834
+ case SSL_ERROR_WANT_CONNECT:
835
+ case SSL_ERROR_WANT_ACCEPT:
836
+ return rc;
837
+ default:
838
+ return (size_t)-1;
839
+ }
827840
}else if(n>0){
828841
rc += n;
829
- }
830
-#ifdef _WIN32
831
- /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832
- ** not require reading in a loop, returning all data in a single
833
- ** call. If we read in a loop on Windows, SSL reads fail. Details:
834
- ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835
- break;
836
-#endif
842
+ /* SSL_read() returns at most 16 KB of data, so retry in this case. */
843
+ if( n!=16384 ) break;
844
+ }
837845
}
838846
return rc;
839847
}
840848
841849
/*
842850
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,10 +811,11 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
 
816 */
817 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
818 int n;
819 size_t rc = 0;
820 SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -821,21 +822,28 @@
821 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822 else if( BIO_eof(pServer->bio) ) return 0;
823 while( nBuf!=rc ){
824 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825 if( n<=0 ){
826 break;
 
 
 
 
 
 
 
 
 
 
 
 
827 }else if(n>0){
828 rc += n;
829 }
830 #ifdef _WIN32
831 /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832 ** not require reading in a loop, returning all data in a single
833 ** call. If we read in a loop on Windows, SSL reads fail. Details:
834 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835 break;
836 #endif
837 }
838 return rc;
839 }
840
841 /*
842
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,10 +811,11 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
816 ** Return (size_t)-1 on error.
817 */
818 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
819 int n;
820 size_t rc = 0;
821 SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -821,21 +822,28 @@
822 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
823 else if( BIO_eof(pServer->bio) ) return 0;
824 while( nBuf!=rc ){
825 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
826 if( n<=0 ){
827 int error = SSL_get_error(pServer->ssl,n);
828 switch( error ){
829 case SSL_ERROR_NONE:
830 case SSL_ERROR_ZERO_RETURN:
831 /* Not all errors relevant with SSL_MODE_AUTO_RETRY. */
832 case SSL_ERROR_WANT_READ:
833 case SSL_ERROR_WANT_WRITE:
834 case SSL_ERROR_WANT_CONNECT:
835 case SSL_ERROR_WANT_ACCEPT:
836 return rc;
837 default:
838 return (size_t)-1;
839 }
840 }else if(n>0){
841 rc += n;
842 /* SSL_read() returns at most 16 KB of data, so retry in this case. */
843 if( n!=16384 ) break;
844 }
 
 
 
 
 
845 }
846 return rc;
847 }
848
849 /*
850
--- src/winhttp.c
+++ src/winhttp.c
@@ -364,10 +364,11 @@
364364
}
365365
while( amt<szHdr ){
366366
if( sslConn ){
367367
#ifdef FOSSIL_ENABLE_SSL
368368
got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369
+ if( got<0 ) goto end_request;
369370
#endif
370371
}else{
371372
got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372373
if( got==SOCKET_ERROR ) goto end_request;
373374
}
@@ -395,10 +396,11 @@
395396
fwrite(zBuf, 1, amt, out);
396397
while( wanted>0 ){
397398
if( sslConn ){
398399
#ifdef FOSSIL_ENABLE_SSL
399400
got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
401
+ if( got<0 ) goto end_request;
400402
#endif
401403
}else{
402404
got = recv(p->s, zBuf, sizeof(zBuf), 0);
403405
if( got==SOCKET_ERROR ) goto end_request;
404406
}
405407
--- src/winhttp.c
+++ src/winhttp.c
@@ -364,10 +364,11 @@
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
 
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
@@ -395,10 +396,11 @@
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
 
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405
--- src/winhttp.c
+++ src/winhttp.c
@@ -364,10 +364,11 @@
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369 if( got<0 ) goto end_request;
370 #endif
371 }else{
372 got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
373 if( got==SOCKET_ERROR ) goto end_request;
374 }
@@ -395,10 +396,11 @@
396 fwrite(zBuf, 1, amt, out);
397 while( wanted>0 ){
398 if( sslConn ){
399 #ifdef FOSSIL_ENABLE_SSL
400 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
401 if( got<0 ) goto end_request;
402 #endif
403 }else{
404 got = recv(p->s, zBuf, sizeof(zBuf), 0);
405 if( got==SOCKET_ERROR ) goto end_request;
406 }
407

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button