[PATCH 1/1] secur32: Validate input buffers in schan_InitializeSecurityContextW().

Hans Leidekker wine at gitlab.winehq.org
Wed Jul 6 03:58:37 CDT 2022


From: Hans Leidekker <hans at codeweavers.com>

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53309
---
 dlls/secur32/schannel.c       | 12 ++++++++++++
 dlls/secur32/tests/schannel.c | 18 ++++++++++++++----
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index 70018e57f7e..34cd3ad9730 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -759,6 +759,17 @@ static void fill_missing_sec_buffer(SecBufferDesc *input, DWORD size)
     }
 }
 
+static BOOL validate_input_buffers(SecBufferDesc *desc)
+{
+    int i;
+    for (i = 0; i < desc->cBuffers; i++)
+    {
+        SecBuffer *buffer = &desc->pBuffers[i];
+        if (buffer->BufferType == SECBUFFER_EMPTY && buffer->cbBuffer) return FALSE;
+    }
+    return TRUE;
+}
+
 /***********************************************************************
  *              InitializeSecurityContextW
  */
@@ -894,6 +905,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
 
         if (pInput)
         {
+            if (!validate_input_buffers(pInput)) return SEC_E_INVALID_TOKEN;
             if ((idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_TOKEN)) == -1) return SEC_E_INCOMPLETE_MESSAGE;
 
             buffer = &pInput->pBuffers[idx];
diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c
index 8322b5a80a5..a531505648f 100644
--- a/dlls/secur32/tests/schannel.c
+++ b/dlls/secur32/tests/schannel.c
@@ -1157,11 +1157,11 @@ static void test_communication(void)
     buffers[1].pBuffers[0].cbBuffer = 4;
     buffers[1].pBuffers[1].cbBuffer = 0;
     buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
+    buffers[1].pBuffers[1].cbBuffer = 0;
     status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
             ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
             0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
-    ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN,
-       "Got unexpected status %#lx.\n", status);
+    ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
     ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
     ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
     ok(buffers[1].pBuffers[1].cbBuffer == 1 ||
@@ -1173,11 +1173,11 @@ static void test_communication(void)
     buffers[1].pBuffers[0].cbBuffer = 5;
     buffers[1].pBuffers[1].cbBuffer = 0;
     buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
+    buffers[1].pBuffers[1].cbBuffer = 0;
     status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
             ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
             0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL);
-    ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN,
-       "Got unexpected status %#lx.\n", status);
+    ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
     ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
     ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
     ok(buffers[1].pBuffers[1].cbBuffer > 5 ||
@@ -1210,6 +1210,16 @@ static void test_communication(void)
         context2.dwLower = context2.dwUpper = 0xdeadbeef;
         buf->BufferType = SECBUFFER_TOKEN;
 
+        buffers[1].cBuffers = 2;
+        buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
+        buffers[1].pBuffers[1].cbBuffer = 0xdeadbeef;
+
+        status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
+            ISC_REQ_USE_SUPPLIED_CREDS,
+            0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
+        ok(status == SEC_E_INVALID_TOKEN, "Got unexpected status %#lx.\n", status);
+
+        buffers[1].cBuffers = 1;
         status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
             ISC_REQ_USE_SUPPLIED_CREDS,
             0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/390



More information about the wine-devel mailing list