[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] [WHQL] NDIS6.0 1c_64bitOIDs / 1c_IOCTLCoverage
Some QUERY OIDs should return truncated results when 4 byte buffers are passed for 8 byte values. Avoid corner cases where the OID would succeed, but not copy data due to wrong buffer sizes. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xennet/adapter.c | 176 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 62 deletions(-) diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index 37b9c37..b094519 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -554,11 +554,16 @@ invalid_parameter: static NDIS_STATUS AdapterQueryGeneralStatistics( IN PXENNET_ADAPTER Adapter, - IN PNDIS_STATISTICS_INFO Info + IN PNDIS_STATISTICS_INFO Info, + IN ULONG BufferLength, + IN OUT PULONG BytesWritten ) { ULONGLONG Value; + if (BufferLength < sizeof(NDIS_STATISTICS_INFO)) + goto fail1; + RtlZeroMemory(Info, sizeof(NDIS_STATISTICS_INFO)); Info->Header.Revision = NDIS_OBJECT_REVISION_1; Info->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; @@ -716,7 +721,12 @@ AdapterQueryGeneralStatistics( Info->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS; Info->ifOutDiscards = 0; + *BytesWritten = sizeof(NDIS_STATISTICS_INFO); return NDIS_STATUS_SUCCESS; + +fail1: + *BytesWritten = 0; + return NDIS_STATUS_BUFFER_TOO_SHORT; } static NDIS_STATUS @@ -724,7 +734,8 @@ AdapterQueryMulticastList( IN PXENNET_ADAPTER Adapter, IN PVOID Buffer, IN ULONG BufferLength, - IN OUT PULONG BytesNeeded + IN OUT PULONG BytesNeeded, + IN OUT PULONG BytesWritten ) { ULONG Count; @@ -749,10 +760,12 @@ AdapterQueryMulticastList( if (!NT_SUCCESS(status)) goto fail2; + *BytesWritten = Count * ETHERNET_ADDRESS_LENGTH; return NDIS_STATUS_SUCCESS; fail2: fail1: + *BytesWritten = 0; return ndisStatus; } @@ -775,7 +788,7 @@ AdapterSetMulticastAddresses( return NDIS_STATUS_SUCCESS; } -static NDIS_STATUS +static FORCEINLINE VOID AdapterGetXmitOk( IN PXENNET_ADAPTER Adapter, OUT PULONGLONG Buffer @@ -803,11 +816,9 @@ AdapterGetXmitOk( &Value); *Buffer += (ULONG)Value; - - return NDIS_STATUS_SUCCESS; } -static NDIS_STATUS +static FORCEINLINE VOID AdapterGetRcvOk( IN PXENNET_ADAPTER Adapter, OUT PULONGLONG Buffer @@ -835,8 +846,6 @@ AdapterGetRcvOk( &Value); *Buffer += (ULONG)Value; - - return NDIS_STATUS_SUCCESS; } static NDIS_STATUS @@ -892,11 +901,16 @@ AdapterGetRcvError( static FORCEINLINE NDIS_STATUS AdapterInterruptModeration( IN PXENNET_ADAPTER Adapter, - IN PNDIS_INTERRUPT_MODERATION_PARAMETERS Params + IN PNDIS_INTERRUPT_MODERATION_PARAMETERS Params, + IN ULONG BufferLength, + IN OUT PULONG BytesWritten ) { UNREFERENCED_PARAMETER(Adapter); + if (BufferLength < sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS)) + goto fail1; + Params->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; Params->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; Params->Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); @@ -904,7 +918,12 @@ AdapterInterruptModeration( Params->Flags = 0; Params->InterruptModeration = NdisInterruptModerationNotSupported; + *BytesWritten = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); return NDIS_STATUS_SUCCESS; + +fail1: + *BytesWritten = 0; + return NDIS_STATUS_BUFFER_TOO_SHORT; } NDIS_HANDLE @@ -1163,6 +1182,28 @@ __SetUlong( } } +static FORCEINLINE NDIS_STATUS +__SetUlong64( + IN PVOID Buffer, + IN ULONG BufferLength, + IN ULONGLONG Source, + IN OUT PULONG SourceLength + ) +{ + if (BufferLength >= sizeof(ULONGLONG)) { + *(PULONGLONG)Buffer = Source; + *SourceLength = sizeof(ULONGLONG); + return NDIS_STATUS_SUCCESS; + } else if (BufferLength == sizeof(ULONG)) { + *(PULONG)Buffer = (ULONG)Source; + *SourceLength = sizeof(ULONG); + return NDIS_STATUS_BUFFER_TOO_SHORT; + } else { + *SourceLength = 0; + return NDIS_STATUS_BUFFER_TOO_SHORT; + } +} + NDIS_STATUS AdapterQueryInformation( IN PXENNET_ADAPTER Adapter, @@ -1175,6 +1216,7 @@ AdapterQueryInformation( ULONG BytesWritten; ULONG Value32; ULONGLONG Value64; + ETHERNET_ADDRESS EthernetAddress; NDIS_STATUS ndisStatus; Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer; @@ -1193,6 +1235,7 @@ AdapterQueryInformation( case OID_PNP_QUERY_POWER: BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE); + BytesWritten = 0; // do nothing break; @@ -1271,41 +1314,47 @@ AdapterQueryInformation( case OID_GEN_STATISTICS: BytesNeeded = BytesWritten = sizeof(NDIS_STATISTICS_INFO); - if (BufferLength >= BytesNeeded) - ndisStatus = AdapterQueryGeneralStatistics(Adapter, - (PNDIS_STATISTICS_INFO)Buffer); + ndisStatus = AdapterQueryGeneralStatistics(Adapter, + (PNDIS_STATISTICS_INFO)Buffer, + BufferLength, + &BytesWritten); break; case OID_802_3_MULTICAST_LIST: ndisStatus = AdapterQueryMulticastList(Adapter, Buffer, BufferLength, - &BytesNeeded); - BytesWritten = BytesNeeded; + &BytesNeeded, + &BytesWritten); break; case OID_802_3_PERMANENT_ADDRESS: + XENVIF_VIF(MacQueryPermanentAddress, + &Adapter->VifInterface, + &EthernetAddress); BytesNeeded = BytesWritten = sizeof(ETHERNET_ADDRESS); - if (BufferLength >= BytesNeeded) { - XENVIF_VIF(MacQueryPermanentAddress, - &Adapter->VifInterface, - (PETHERNET_ADDRESS)Buffer); - } + ndisStatus = __CopyBuffer(Buffer, + BufferLength, + &EthernetAddress, + &BytesWritten); break; case OID_802_3_CURRENT_ADDRESS: + XENVIF_VIF(MacQueryCurrentAddress, + &Adapter->VifInterface, + &EthernetAddress); BytesNeeded = BytesWritten = sizeof(ETHERNET_ADDRESS); - if (BufferLength >= BytesNeeded) { - XENVIF_VIF(MacQueryCurrentAddress, - &Adapter->VifInterface, - (PETHERNET_ADDRESS)Buffer); - } + ndisStatus = __CopyBuffer(Buffer, + BufferLength, + &EthernetAddress, + &BytesWritten); break; case OID_GEN_MAXIMUM_FRAME_SIZE: ndisStatus = __SetUlong(Buffer, BufferLength, - Adapter->MaximumFrameSize - sizeof(ETHERNET_TAGGED_HEADER), + Adapter->MaximumFrameSize - + sizeof(ETHERNET_TAGGED_HEADER), &BytesWritten); break; @@ -1345,13 +1394,15 @@ AdapterQueryInformation( break; case OID_GEN_MEDIA_CONNECT_STATUS: - if (BufferLength >= sizeof(ULONG)) { - XENVIF_VIF(MacQueryState, - &Adapter->VifInterface, - (PNET_IF_MEDIA_CONNECT_STATE)Buffer, - NULL, - NULL); - } + XENVIF_VIF(MacQueryState, + &Adapter->VifInterface, + (PNET_IF_MEDIA_CONNECT_STATE)&Value32, + NULL, + NULL); + ndisStatus = __SetUlong(Buffer, + BufferLength, + Value32, + &BytesWritten); break; case OID_GEN_MAXIMUM_SEND_PACKETS: @@ -1362,40 +1413,43 @@ AdapterQueryInformation( break; case OID_GEN_CURRENT_PACKET_FILTER: - if (BufferLength >= sizeof(ULONG)) { - AdapterGetPacketFilter(Adapter, - (PULONG)Buffer); - } + AdapterGetPacketFilter(Adapter, &Value32); + ndisStatus = __SetUlong(Buffer, + BufferLength, + Value32, + &BytesWritten); break; case OID_GEN_XMIT_OK: - BytesNeeded = BytesWritten = sizeof(ULONGLONG); - if (BufferLength >= BytesNeeded) { - ndisStatus = AdapterGetXmitOk(Adapter, - (PULONGLONG)Buffer); - } + AdapterGetXmitOk(Adapter, &Value64); + ndisStatus = __SetUlong64(Buffer, + BufferLength, + Value64, + &BytesWritten); break; case OID_GEN_RCV_OK: - BytesNeeded = BytesWritten = sizeof(ULONGLONG); - if (BufferLength >= BytesNeeded) { - ndisStatus = AdapterGetRcvOk(Adapter, - (PULONGLONG)Buffer); - } + AdapterGetRcvOk(Adapter, &Value64); + ndisStatus = __SetUlong64(Buffer, + BufferLength, + Value64, + &BytesWritten); break; case OID_GEN_XMIT_ERROR: - if (BufferLength >= BytesNeeded) { - ndisStatus = AdapterGetXmitError(Adapter, - (PULONG)Buffer); - } + AdapterGetXmitError(Adapter, &Value32); + ndisStatus = __SetUlong(Buffer, + BufferLength, + Value32, + &BytesWritten); break; case OID_GEN_RCV_ERROR: - if (BufferLength >= BytesNeeded) { - ndisStatus = AdapterGetRcvError(Adapter, - (PULONG)Buffer); - } + AdapterGetRcvError(Adapter, &Value32); + ndisStatus = __SetUlong(Buffer, + BufferLength, + Value32, + &BytesWritten); break; case OID_GEN_RCV_NO_BUFFER: @@ -1550,11 +1604,11 @@ AdapterQueryInformation( break; case OID_GEN_INTERRUPT_MODERATION: - BytesNeeded = BytesWritten = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - if (BufferLength >= BytesWritten) { - ndisStatus = AdapterInterruptModeration(Adapter, - (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer); - } + BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + ndisStatus = AdapterInterruptModeration(Adapter, + (PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer, + BufferLength, + &BytesWritten); break; case OID_IP4_OFFLOAD_STATS: @@ -1576,9 +1630,7 @@ AdapterQueryInformation( break; } - if (ndisStatus == NDIS_STATUS_SUCCESS) - Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; - + Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; return ndisStatus; -- 1.9.4.msysgit.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |