Hans Leidekker : winhttp: Consistently validate the buffer in option query functions.

Alexandre Julliard julliard at winehq.org
Fri Sep 17 16:03:09 CDT 2021


Module: wine
Branch: master
Commit: 73c107fd532363d7f98f77b4c4d5704c66160232
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=73c107fd532363d7f98f77b4c4d5704c66160232

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Sep 17 14:41:14 2021 +0200

winhttp: Consistently validate the buffer in option query functions.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winhttp/session.c | 103 ++++++++++++++++++++++++++-----------------------
 1 file changed, 54 insertions(+), 49 deletions(-)

diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 88e305da864..659a1ec8cee 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -82,6 +82,17 @@ static void session_destroy( struct object_header *hdr )
     free( session );
 }
 
+static BOOL validate_buffer( void *buffer, DWORD *buflen, DWORD required )
+{
+    if (!buffer || *buflen < required)
+    {
+        *buflen = required;
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        return FALSE;
+    }
+    return TRUE;
+}
+
 static BOOL session_query_option( struct object_header *hdr, DWORD option, void *buffer, DWORD *buflen )
 {
     struct session *session = (struct session *)hdr;
@@ -90,38 +101,43 @@ static BOOL session_query_option( struct object_header *hdr, DWORD option, void
     {
     case WINHTTP_OPTION_REDIRECT_POLICY:
     {
-        if (!buffer || *buflen < sizeof(DWORD))
-        {
-            *buflen = sizeof(DWORD);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
 
         *(DWORD *)buffer = hdr->redirect_policy;
         *buflen = sizeof(DWORD);
         return TRUE;
     }
     case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = session->resolve_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = session->connect_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_SEND_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = session->send_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = session->receive_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = session->receive_response_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
@@ -314,38 +330,43 @@ static BOOL connect_query_option( struct object_header *hdr, DWORD option, void
     {
     case WINHTTP_OPTION_PARENT_HANDLE:
     {
-        if (!buffer || *buflen < sizeof(HINTERNET))
-        {
-            *buflen = sizeof(HINTERNET);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(HINTERNET) )) return FALSE;
 
         *(HINTERNET *)buffer = ((struct object_header *)connect->session)->handle;
         *buflen = sizeof(HINTERNET);
         return TRUE;
     }
     case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = connect->session->resolve_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = connect->session->connect_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_SEND_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = connect->session->send_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = connect->session->receive_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = connect->session->receive_response_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
@@ -669,12 +690,7 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
         DWORD flags;
         int bits;
 
-        if (!buffer || *buflen < sizeof(flags))
-        {
-            *buflen = sizeof(flags);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(flags) )) return FALSE;
 
         flags = request->security_flags;
         if (request->netconn)
@@ -695,12 +711,7 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
     {
         const CERT_CONTEXT *cert;
 
-        if (!buffer || *buflen < sizeof(cert))
-        {
-            *buflen = sizeof(cert);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(cert) )) return FALSE;
 
         if (!(cert = CertDuplicateCertificateContext( request->server_cert ))) return FALSE;
         *(CERT_CONTEXT **)buffer = (CERT_CONTEXT *)cert;
@@ -715,13 +726,7 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
 
         FIXME("partial stub\n");
 
-        if (!buffer || *buflen < sizeof(*ci))
-        {
-            *buflen = sizeof(*ci);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
-        if (!cert) return FALSE;
+        if (!validate_buffer( buffer, buflen, sizeof(*ci) ) || !cert) return FALSE;
 
         ci->ftExpiry = cert->pCertInfo->NotAfter;
         ci->ftStart  = cert->pCertInfo->NotBefore;
@@ -741,12 +746,7 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
     }
     case WINHTTP_OPTION_SECURITY_KEY_BITNESS:
     {
-        if (!buffer || *buflen < sizeof(DWORD))
-        {
-            *buflen = sizeof(DWORD);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
 
         *(DWORD *)buffer = request->netconn ? netconn_get_cipher_strength( request->netconn ) : 0;
         *buflen = sizeof(DWORD);
@@ -759,12 +759,8 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
         socklen_t len = sizeof(local);
         const struct sockaddr *remote = (const struct sockaddr *)&request->connect->sockaddr;
 
-        if (!buffer || *buflen < sizeof(*info))
-        {
-            *buflen = sizeof(*info);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(*info) )) return FALSE;
+
         if (!request->netconn)
         {
             SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE );
@@ -777,26 +773,36 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
         return TRUE;
     }
     case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->resolve_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->connect_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_SEND_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->send_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->receive_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->receive_response_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
@@ -818,11 +824,15 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void
         return TRUE;
 
     case WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         *(DWORD *)buffer = request->max_redirects;
         *buflen = sizeof(DWORD);
         return TRUE;
 
     case WINHTTP_OPTION_HTTP_PROTOCOL_USED:
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD) )) return FALSE;
+
         FIXME("WINHTTP_OPTION_HTTP_PROTOCOL_USED\n");
         *(DWORD *)buffer = 0;
         *buflen = sizeof(DWORD);
@@ -1214,12 +1224,7 @@ static BOOL query_option( struct object_header *hdr, DWORD option, void *buffer,
     {
     case WINHTTP_OPTION_CONTEXT_VALUE:
     {
-        if (!buffer || *buflen < sizeof(DWORD_PTR))
-        {
-            *buflen = sizeof(DWORD_PTR);
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
+        if (!validate_buffer( buffer, buflen, sizeof(DWORD_PTR) )) return FALSE;
 
         *(DWORD_PTR *)buffer = hdr->context;
         *buflen = sizeof(DWORD_PTR);




More information about the wine-cvs mailing list