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