Skip to content

Commit

Permalink
- Fix issue #18 that causes a BSOD when a NULL pointer is passed as an
Browse files Browse the repository at this point in the history
  address parameter to either WinDivertRecv or WinDivertSend.
- Use better NT_STATUS codes for some errors.
- Bump the version number to WinDivert 1.1.4
  • Loading branch information
basil00 committed Apr 2, 2014
1 parent 874d147 commit 98c4a51
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ WinDivert 1.1.1
WinDivert 1.1.2-rc
- Renamed drivers to "WinDivert32.sys" and "WinDivert64.sys". Both can
exist in the same directory, and WinDivert.dll automatically loads the
right correct version.
correct version.
- Deprecate both the WinDivert.inf and WdfCoInstaller*.dll files.
WinDivert 1.1.3
- Fixed a bug that caused some outbound TCP packets to be lost.
- Fixed a bug causing outbound TCP packets to be sometimes lost.
WinDivert 1.1.4
- Fixed a BSOD that occurs when NULL is passed as the address parameter to
WinDivertRecv(..) or WinDivertSend(..).
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.3
1.1.4
48 changes: 25 additions & 23 deletions sys/windivert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,7 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)

if (inbuflen != sizeof(struct windivert_ioctl_s))
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("input buffer not an ioctl message header", status);
goto windivert_caller_context_error;
}
Expand All @@ -1653,7 +1653,7 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
if (ioctl->version != WINDIVERT_IOCTL_VERSION ||
ioctl->magic != WINDIVERT_IOCTL_MAGIC)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("input buffer contained a bad ioctl message header",
status);
goto windivert_caller_context_error;
Expand All @@ -1667,14 +1667,15 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
DEBUG_ERROR("failed to allocate request context for ioctl", status);
goto windivert_caller_context_error;
}
req_context->addr = NULL;
if (ioctl->arg == (UINT64)NULL)
{
goto windivert_caller_context_exit;
}
switch (params.Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_WINDIVERT_RECV:
if ((PVOID)ioctl->arg == NULL)
{
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("null arg pointer for RECV ioctl", status);
goto windivert_caller_context_error;
}
status = WdfRequestProbeAndLockUserBufferForWrite(request,
(PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj);
if (!NT_SUCCESS(status))
Expand All @@ -1686,6 +1687,12 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
break;

case IOCTL_WINDIVERT_SEND:
if ((PVOID)ioctl->arg == NULL)
{
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("null arg pointer for SEND ioctl", status);
goto windivert_caller_context_error;
}
status = WdfRequestProbeAndLockUserBufferForRead(request,
(PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj);
if (!NT_SUCCESS(status))
Expand All @@ -1697,11 +1704,6 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
break;

case IOCTL_WINDIVERT_START_FILTER:
status = STATUS_INVALID_DEVICE_REQUEST;
DEBUG_ERROR("arg pointer is non-NULL for SET_FILTER ioctl",
status);
goto windivert_caller_context_error;

case IOCTL_WINDIVERT_SET_LAYER:
case IOCTL_WINDIVERT_SET_PRIORITY:
case IOCTL_WINDIVERT_SET_FLAGS:
Expand Down Expand Up @@ -1809,8 +1811,8 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,

if (InterlockedExchange(&context->filter_on, TRUE) == TRUE)
{
status = STATUS_INVALID_DEVICE_REQUEST;
DEBUG_ERROR("duplicate SET_FILTER ioctl", status);
status = STATUS_INVALID_DEVICE_STATE;
DEBUG_ERROR("duplicate START_FILTER ioctl", status);
goto windivert_ioctl_exit;
}

Expand All @@ -1823,7 +1825,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
context->filter = windivert_filter_compile(filter, filter_len);
if (context->filter == NULL)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to compile filter", status);
goto windivert_ioctl_exit;
}
Expand All @@ -1844,7 +1846,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
ioctl = (windivert_ioctl_t)inbuf;
if (ioctl->arg > WINDIVERT_LAYER_MAX)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set layer; value too big", status);
goto windivert_ioctl_exit;
}
Expand All @@ -1856,7 +1858,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
if (ioctl->arg < WINDIVERT_PRIORITY_MIN ||
ioctl->arg > WINDIVERT_PRIORITY_MAX)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set priority; value out of range",
status);
goto windivert_ioctl_exit;
Expand All @@ -1869,7 +1871,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
ioctl = (windivert_ioctl_t)inbuf;
if (!WINDIVERT_FLAGS_VALID(ioctl->arg))
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set flags; invalid flags value",
status);
goto windivert_ioctl_exit;
Expand All @@ -1886,7 +1888,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
if (value < WINDIVERT_PARAM_QUEUE_LEN_MIN ||
value > WINDIVERT_PARAM_QUEUE_LEN_MAX)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set queue length; invalid "
"value", status);
goto windivert_ioctl_exit;
Expand All @@ -1898,7 +1900,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
if (value < WINDIVERT_PARAM_QUEUE_TIME_MIN ||
value > WINDIVERT_PARAM_QUEUE_TIME_MAX)
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set queue time; invalid "
"value", status);
goto windivert_ioctl_exit;
Expand All @@ -1907,7 +1909,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
break;

default:
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to set parameter; invalid parameter",
status);
goto windivert_ioctl_exit;
Expand All @@ -1918,7 +1920,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
ioctl = (windivert_ioctl_t)inbuf;
if (outbuflen != sizeof(UINT64))
{
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to get parameter; invalid output "
"buffer size", status);
goto windivert_ioctl_exit;
Expand All @@ -1933,7 +1935,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
*valptr = context->timer_timeout;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
status = STATUS_INVALID_PARAMETER;
DEBUG_ERROR("failed to get parameter; invalid parameter",
status);
goto windivert_ioctl_exit;
Expand Down
4 changes: 2 additions & 2 deletions sys/windivert.rc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"WinDivert network packet capture and (re)injection driver"
#define VER_INTERNALNAME_STR "WinDivert.sys"
#define VER_ORIGINALFILENAME_STR "WinDivert.sys"
#define VER_PRODUCTVERSION 1.1.3
#define VER_PRODUCTVERSION_STR "1.1.3"
#define VER_PRODUCTVERSION 1.1.4
#define VER_PRODUCTVERSION_STR "1.1.4"
#define VER_COMPANYNAME_STR "Basil's Projects"
#define VER_LEGALCOPYRIGHT_YEARS "2011-2014"
#define VER_LEGALCOPYRIGHT_STR \
Expand Down

0 comments on commit 98c4a51

Please sign in to comment.