[Winpcap-bugs] security vulnerabilities in WinPCap 4.1 Beta 3
Sebastian Gottschalk
seppig_relay at gmx.de
Wed Feb 13 23:12:03 GMT 2008
Dear Sir or Madam,
I completed my analysis of WinPCap 4.1 Beta 3 and found 3 major problems in
at least 17 functions, aside from those I had already reported to you.
Problem 1: NPF_Open doesn't check whether a device has already been opened,
and since createDevice() creates devices with non-exclusive access (even
though exclusive access would have to be enforced by the driver anyway),
opening a device more than once causes the structure 'Open' to be
initialized more than once, always leaking the memory, spinlock and event
resources associated with it. Since NPF_Close doesn't care either, opening a
device twice and closing it just once makes 'Open' effectively become a
dangling pointer, which will mess up NPF_Cleanup. Even further, closing the
device makes IrpSp->DeviceExtension->FsContext an undefined variable, and
since this function read 'Open' from there another memory leak and another
dangling pointer may occur.
Microsoft recommends as a solution to keep track of all FsContext in
NPF_Open and rejecting all duplicates. They also provide two functions
(FsRtlLookupPerStreamContext, FsRtlInsertPerStreamContext) to handle this
issue on behalf of the driver, which are available on Windows 2000 SP4 +
Rollup and Windows XP and later.
Problem 2: The following fields of 'Open' aren't locked and therefore not
properly synchronized: Mode, SkipSentPackets, ReadEvent, ReaderSN, WriterSN,
Size, Timeout, NWrites, MinToCopy. At least 'Size' leads to a race condition
and into a buffer overflow, 'ReadEvent' causes a leak of event resource.
Problem 3: Irp->AssociatedIrp->SystemBuffer is almost never validated, and
even if so, totally improperly. Only NP_IoControl!BIOCGSTATS does a little
bit of validation, but utilizes memory locking (causing a Denial of Service
if a sufficiently large buffer is provided) and fails to catch the exception
EXCEPTION_DATATYPE_MISALIGNMENT. It also validates in cases where no
validation would be necessary (f.e. if it's called by a lower level filter
driver that has already validated the buffer). NPF_Read seems to do
something that might be intended as validation, but surely isn't.
This is quite bad since proper and correct validation can be actually very
simple and performant, about like this:
include <rx.h> // for FlagOn macro
IrpSp = IoGetIrpStackLocation(Irp);
PWHATEVER foo = (PWHATEVER)Irp->AssociatedIrp.SystemBuffer;
__try {
if ( (Irp->RequestorMode == UserMode) || FlagOn(irpSp->Flags,
SL_FORCE_ACCESS_CHECK))
ProbeForRead((PWHATEVER)foo,sizeof(WHATEVER)
,TYPE_ALIGNMENT(WHATEVER));
// use ProbeForWrite for write access
// all subsequent read/write access must be within the try/except
ULONG u = foo->field;
} __except( (GetExceptionCode() == STATUS_ACCESS_VIOLATION) ||
(GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
// if the exception was not our fault, then propagate it
{
// cleanup
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
Sincerely,
Sebastian Gottschalk
More information about the Winpcap-bugs
mailing list