From 02932d03cda16f1564e049b97beb1084ba2015b3 Mon Sep 17 00:00:00 2001 From: Stan Smith Date: Thu, 26 Aug 2010 22:22:58 +0000 Subject: [PATCH] [IPOIB,IPOIB_NDIS6_CM] Fixing the bug when NDIS sends OID_GEN_NETWORK_LAYER_ADDRESSES with the list of new addresses with invalid formatting (happened when AddressCount =5) NDIS sends NETWORK_ADDRESS_LIST structure, which contains an array of NETWORK_ADDRESS structures of variable size. The calculation of the next address offset is based on AddressLength; in a case when this field contains wrong data, one can get access violation error Signed-off by: Alexander Naslednikov (xalex at mellanox.co.il) git-svn-id: svn://openib.tc.cornell.edu/gen1@2876 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/ulp/ipoib/kernel/ipoib_driver.c | 62 +++++++++---------- .../ipoib_NDIS6_CM/kernel/ipoib_driver.cpp | 59 +++++++++--------- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/trunk/ulp/ipoib/kernel/ipoib_driver.c b/trunk/ulp/ipoib/kernel/ipoib_driver.c index a29347e0..5a27df65 100644 --- a/trunk/ulp/ipoib/kernel/ipoib_driver.c +++ b/trunk/ulp/ipoib/kernel/ipoib_driver.c @@ -2203,30 +2203,29 @@ __ipoib_set_net_addr( cl_vector_get_ptr( &p_adapter->ip_vector, idx ); p_net_addr_oid = (PNETWORK_ADDRESS)p_net_addrs->Address; - for( i = 0; i < p_net_addrs->AddressCount; ++i, p_net_addr_oid = - (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + - FIELD_OFFSET(NETWORK_ADDRESS, Address) + - p_net_addr_oid->AddressLength) ) + for( i = 0; i < p_net_addrs->AddressCount; ++i ) { - if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP ) - { - IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_OID, - ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, " - "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType, - NDIS_PROTOCOL_ID_TCP_IP)); - continue; - } - + // Here we check that the data stored at 'AddressLength' field is valid; + // otherwise, it can lead to a memory violation (happened when AddressCount was > 1) if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP) { - IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_OID, + IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, " "should be %d\n", port_num, i, p_net_addr_oid->AddressLength, NETWORK_ADDRESS_LENGTH_IP)); - continue; + ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX ); + break; } + ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP ); + + p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + + FIELD_OFFSET(NETWORK_ADDRESS, Address) + + p_net_addr_oid->AddressLength) ; + + + p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address; if( !cl_memcmp( &p_ip_addr->in_addr, &p_addr_item->address.as_ulong, sizeof(ULONG) ) ) @@ -2266,36 +2265,37 @@ __ipoib_set_net_addr( /* Now look for new addresses */ p_net_addr_oid = (NETWORK_ADDRESS *)p_net_addrs->Address; idx = 0; - for( i = 0; i < p_net_addrs->AddressCount; i++, p_net_addr_oid = - (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + - FIELD_OFFSET(NETWORK_ADDRESS, Address) + p_net_addr_oid->AddressLength) ) + + for( i = 0; i < p_net_addrs->AddressCount; ++i ) { - if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP ) - { - IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID, - ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, " - "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType, - NDIS_PROTOCOL_ID_TCP_IP)); - continue; - } - + // Here we check that the data stored at 'AddressLength' field is valid; + // otherwise, it can lead to a memory violation (happened when AddressCount was > 1) if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP) { - IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID, + IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, " "should be %d\n", port_num, i, p_net_addr_oid->AddressLength, NETWORK_ADDRESS_LENGTH_IP)); - continue; + ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX ); + break; + } - + + ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP ); + + p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + + FIELD_OFFSET(NETWORK_ADDRESS, Address) + + p_net_addr_oid->AddressLength) ; + + p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address; /* Size the vector as needed. */ if( cl_vector_get_size( &p_adapter->ip_vector ) <= idx ) cl_vector_set_size( &p_adapter->ip_vector, idx + 1 ); - p_addr_item = cl_vector_get_ptr( &p_adapter->ip_vector, idx ); + p_addr_item = (net_address_item_t *) cl_vector_get_ptr( &p_adapter->ip_vector, idx ); if( !cl_memcmp( &p_ip_addr->in_addr, &p_addr_item->address.as_ulong, sizeof(ULONG) ) ) { diff --git a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp index 850b2d43..c189e950 100644 --- a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp +++ b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp @@ -3553,29 +3553,27 @@ __ipoib_set_net_addr( cl_vector_get_ptr( &p_adapter->ip_vector, idx ); p_net_addr_oid = (PNETWORK_ADDRESS)p_net_addrs->Address; - for( i = 0; i < p_net_addrs->AddressCount; ++i, p_net_addr_oid = - (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + - FIELD_OFFSET(NETWORK_ADDRESS, Address) + - p_net_addr_oid->AddressLength) ) + for( i = 0; i < p_net_addrs->AddressCount; ++i ) { - if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP ) - { - IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_OID, - ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, " - "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType, - NDIS_PROTOCOL_ID_TCP_IP)); - continue; - } - + // Here we check that the data stored at 'AddressLength' field is valid; + // otherwise, it can lead to a memory violation (happened when AddressCount was > 1) if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP) { - IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_OID, + IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, " "should be %d\n", port_num, i, p_net_addr_oid->AddressLength, NETWORK_ADDRESS_LENGTH_IP)); - continue; + ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX ); + break; } + + ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP ); + + p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + + FIELD_OFFSET(NETWORK_ADDRESS, Address) + + p_net_addr_oid->AddressLength) ; + p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address; if( !cl_memcmp( &p_ip_addr->in_addr, @@ -3616,29 +3614,30 @@ __ipoib_set_net_addr( /* Now look for new addresses */ p_net_addr_oid = (NETWORK_ADDRESS *)p_net_addrs->Address; idx = 0; - for( i = 0; i < p_net_addrs->AddressCount; i++, p_net_addr_oid = - (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + - FIELD_OFFSET(NETWORK_ADDRESS, Address) + p_net_addr_oid->AddressLength) ) + + for( i = 0; i < p_net_addrs->AddressCount; ++i ) { - if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP ) - { - IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID, - ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, " - "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType, - NDIS_PROTOCOL_ID_TCP_IP)); - continue; - } - + // Here we check that the data stored at 'AddressLength' field is valid; + // otherwise, it can lead to a memory violation (happened when AddressCount was > 1) if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP) { - IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID, + IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, " "should be %d\n", port_num, i, p_net_addr_oid->AddressLength, NETWORK_ADDRESS_LENGTH_IP)); - continue; + ASSERT ( p_net_addr_oid->AddressLength == NETWORK_ADDRESS_LENGTH_IPX ); + break; + } - + + ASSERT( p_net_addr_oid->AddressType == NDIS_PROTOCOL_ID_TCP_IP ); + + p_net_addr_oid = (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid + + FIELD_OFFSET(NETWORK_ADDRESS, Address) + + p_net_addr_oid->AddressLength) ; + + p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address; /* Size the vector as needed. */ -- 2.41.0