secur32: Validate input buffers in schan_InitializeSecurityContextW().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53309
This commit is contained in:
Hans Leidekker 2022-07-06 10:49:31 +02:00 committed by Alexandre Julliard
parent 7623d0a6f5
commit 738a5b53a4
2 changed files with 26 additions and 4 deletions

View file

@ -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 * InitializeSecurityContextW
*/ */
@ -894,6 +905,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
if (pInput) 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; if ((idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_TOKEN)) == -1) return SEC_E_INCOMPLETE_MESSAGE;
buffer = &pInput->pBuffers[idx]; buffer = &pInput->pBuffers[idx];

View file

@ -1157,11 +1157,11 @@ static void test_communication(void)
buffers[1].pBuffers[0].cbBuffer = 4; buffers[1].pBuffers[0].cbBuffer = 4;
buffers[1].pBuffers[1].cbBuffer = 0; buffers[1].pBuffers[1].cbBuffer = 0;
buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY; buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
buffers[1].pBuffers[1].cbBuffer = 0;
status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN, ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
"Got unexpected status %#lx.\n", status);
ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); 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[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
ok(buffers[1].pBuffers[1].cbBuffer == 1 || 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[0].cbBuffer = 5;
buffers[1].pBuffers[1].cbBuffer = 0; buffers[1].pBuffers[1].cbBuffer = 0;
buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY; buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
buffers[1].pBuffers[1].cbBuffer = 0;
status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL); 0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL);
ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN, ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
"Got unexpected status %#lx.\n", status);
ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); 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[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
ok(buffers[1].pBuffers[1].cbBuffer > 5 || ok(buffers[1].pBuffers[1].cbBuffer > 5 ||
@ -1210,6 +1210,16 @@ static void test_communication(void)
context2.dwLower = context2.dwUpper = 0xdeadbeef; context2.dwLower = context2.dwUpper = 0xdeadbeef;
buf->BufferType = SECBUFFER_TOKEN; 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", status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
ISC_REQ_USE_SUPPLIED_CREDS, ISC_REQ_USE_SUPPLIED_CREDS,
0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);