From: Steve Chew (stechew) Date: Tue, 25 Feb 2020 19:06:51 +0000 (+0000) Subject: Merge pull request #1954 in SNORT/snort3 from ~OKHOMIAK/snort3:big_endian_system_buil... X-Git-Tag: 3.0.0-269~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=374f6234fede2b87e1548c4f3e46bd8f90577cf6;p=thirdparty%2Fsnort3.git Merge pull request #1954 in SNORT/snort3 from ~OKHOMIAK/snort3:big_endian_system_build to master Squashed commit of the following: commit d402a299c4168f67eea200fc0e5973071a6bc5c1 Author: Oleksii Khomiakovskyi Date: Mon Jan 20 16:03:04 2020 +0200 build: fix build on big-endian systems moved little-endian arrays conversion macros in a common header added macros to convert little endian to host order for unaligned access made unit tests independent of types size and system arch --- diff --git a/src/codecs/ip/cd_ipv4.cc b/src/codecs/ip/cd_ipv4.cc index c61ef98d2..a4f2b1835 100644 --- a/src/codecs/ip/cd_ipv4.cc +++ b/src/codecs/ip/cd_ipv4.cc @@ -374,8 +374,8 @@ void Ipv4Codec::IP4AddrTests( /* Loopback traffic - don't use htonl for speed reasons - * s_addr is always in network order */ #ifdef WORDS_BIGENDIAN - msb_src = (iph.ip_src >> 24); - msb_dst = (iph.ip_dst >> 24); + msb_src = (uint8_t)(iph->ip_src >> 24); + msb_dst = (uint8_t)(iph->ip_dst >> 24); #else msb_src = (uint8_t)(iph->ip_src & 0xff); msb_dst = (uint8_t)(iph->ip_dst & 0xff); diff --git a/src/connectors/tcp_connector/test/tcp_connector_test.cc b/src/connectors/tcp_connector/test/tcp_connector_test.cc index 5ec7fb82f..51f4abfb5 100644 --- a/src/connectors/tcp_connector/test/tcp_connector_test.cc +++ b/src/connectors/tcp_connector/test/tcp_connector_test.cc @@ -93,6 +93,7 @@ int poll (struct pollfd* fds, nfds_t nfds, int) if ( s_poll_error ) return -1; + fds[0].revents = 0; if ( s_poll_undesirable ) { fds[0].revents |= POLLHUP; diff --git a/src/flow/test/flow_cache_test.cc b/src/flow/test/flow_cache_test.cc index 411044b85..21f7e7764 100644 --- a/src/flow/test/flow_cache_test.cc +++ b/src/flow/test/flow_cache_test.cc @@ -88,8 +88,8 @@ bool HighAvailabilityManager::in_standby(Flow*) { return true; } SfIpRet SfIp::set(void const*, int) { return SFIP_SUCCESS; } namespace memory { -void MemoryCap::update_allocations(unsigned long) { } -void MemoryCap::update_deallocations(unsigned long) { } +void MemoryCap::update_allocations(size_t) { } +void MemoryCap::update_deallocations(size_t) { } bool MemoryCap::over_threshold() { return true; } } diff --git a/src/host_tracker/test/host_cache_test.cc b/src/host_tracker/test/host_cache_test.cc index 2a2ba347c..cad83895f 100644 --- a/src/host_tracker/test/host_cache_test.cc +++ b/src/host_tracker/test/host_cache_test.cc @@ -50,17 +50,19 @@ TEST_GROUP(host_cache) // Test HashIp TEST(host_cache, hash_test) { - size_t expected_hash_val = 4521729; size_t actual_hash_val; - uint8_t hk[16] = - { 0x0a,0xff,0x12,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x56,0x00,0x00,0x00,0x00,0x00 }; HashIp hash_hk; SfIp ip; - ip.set(hk); + ip.pton(AF_INET6, "aff:1200::b00:5600:0:0"); actual_hash_val = hash_hk(ip); - CHECK(actual_hash_val == expected_hash_val); + +#if defined(WORDS_BIGENDIAN) + CHECK(actual_hash_val == (size_t)143908479889833984); +#else + CHECK(actual_hash_val == (size_t)4521729); +#endif } int main(int argc, char** argv) diff --git a/src/network_inspectors/appid/appid_detector.h b/src/network_inspectors/appid/appid_detector.h index 617f98492..2f22f0ea4 100644 --- a/src/network_inspectors/appid/appid_detector.h +++ b/src/network_inspectors/appid/appid_detector.h @@ -181,13 +181,5 @@ protected: ServiceDetectorPorts service_ports; }; -#if defined(WORDS_BIGENDIAN) -#define LETOHS(p) BYTE_SWAP_16(*((const uint16_t*)(p))) -#define LETOHL(p) BYTE_SWAP_32(*((const uint32_t*)(p))) -#else -#define LETOHS(p) (*((const uint16_t*)(p))) -#define LETOHL(p) (*((const uint32_t*)(p))) -#endif - #endif diff --git a/src/network_inspectors/appid/service_plugins/service_netbios.cc b/src/network_inspectors/appid/service_plugins/service_netbios.cc index 9ffef77e9..e4579d93f 100644 --- a/src/network_inspectors/appid/service_plugins/service_netbios.cc +++ b/src/network_inspectors/appid/service_plugins/service_netbios.cc @@ -25,9 +25,11 @@ #include "service_netbios.h" +#include "protocols/packet.h" +#include "utils/endian.h" + #include "app_info_table.h" #include "dcerpc.h" -#include "protocols/packet.h" using namespace snort; @@ -652,7 +654,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int return; data += wc; size -= wc; - byte_count = LETOHS(data); + byte_count = LETOHS_UNALIGNED(data); data += sizeof(byte_count); size -= sizeof(byte_count); if (size < byte_count) @@ -663,7 +665,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int { if (wc == 8) { - uint16_t sec_len = LETOHS(&resp->sec_len); + uint16_t sec_len = LETOHS_UNALIGNED(&resp->sec_len); if (sec_len >= byte_count) return; data += sec_len; @@ -683,7 +685,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int { if (wc == 34) { - capabilities = LETOHL(&np->capabilities); + capabilities = LETOHL_UNALIGNED(&np->capabilities); if (capabilities & SERVICE_SMB_CAPABILITIES_EXTENDED_SECURITY) return; unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) || unicode; @@ -1128,7 +1130,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args) { goto not_mailslot; } - server_type = LETOHL(&browser->server_type); + server_type = LETOHL_UNALIGNED(&browser->server_type); add_smb_info(args.asd, browser->major, browser->minor, server_type); } not_mailslot: diff --git a/src/network_inspectors/perf_monitor/cpu_tracker.cc b/src/network_inspectors/perf_monitor/cpu_tracker.cc index 7c3c2dab5..6427e8574 100644 --- a/src/network_inspectors/perf_monitor/cpu_tracker.cc +++ b/src/network_inspectors/perf_monitor/cpu_tracker.cc @@ -155,8 +155,7 @@ TEST_CASE("timeval to scalar", "[cpu_tracker]") t.tv_usec = 0; CHECK(get_microseconds(t) == 0); - //integer overflow - t.tv_sec = 0xFFFFFFFF; + t.tv_sec = std::numeric_limits::max(); t.tv_usec = 999999; auto ms = get_microseconds(t); t2.tv_sec = ms / 1000000; diff --git a/src/network_inspectors/perf_monitor/csv_formatter.cc b/src/network_inspectors/perf_monitor/csv_formatter.cc index c4da5d1a6..aa291ddbf 100644 --- a/src/network_inspectors/perf_monitor/csv_formatter.cc +++ b/src/network_inspectors/perf_monitor/csv_formatter.cc @@ -110,7 +110,7 @@ TEST_CASE("csv output", "[CSVFormatter]") const char* cooked = "#timestamp,name.one,name.two,other.three,other.five,other.kvp\n" "1234567890,0,1,2,hellothere,3,50,60,70\n" - "2345678901,0,0,0,,0\n"; + "2145678903,0,0,0,,0\n"; FILE* fh = tmpfile(); CSVFormatter f("csv_formatter"); @@ -135,7 +135,7 @@ TEST_CASE("csv output", "[CSVFormatter]") three = 0; five[0] = '\0'; kvp.clear(); - f.write(fh, (time_t)2345678901); + f.write(fh, (time_t)2145678903); auto size = ftell(fh); char* fake_file = new char[size + 1]; diff --git a/src/network_inspectors/perf_monitor/json_formatter.cc b/src/network_inspectors/perf_monitor/json_formatter.cc index 2d25ea122..313e5ef98 100644 --- a/src/network_inspectors/perf_monitor/json_formatter.cc +++ b/src/network_inspectors/perf_monitor/json_formatter.cc @@ -133,7 +133,7 @@ void JSONFormatter::finalize_output(FILE* fh) #include "catch/catch.hpp" std::string cooked = R"g([{"timestamp":1234567890,"name":{"one":1},"str":{"five":"hellothere"},)g" - R"g("vec":{"vector":{"0":50,"2":70}}},{"timestamp":2345678901}])g" "\n"; + R"g("vec":{"vector":{"0":50,"2":70}}},{"timestamp":2145678903}])g" "\n"; TEST_CASE("json output", "[JSONFormatter]") { @@ -165,7 +165,7 @@ TEST_CASE("json output", "[JSONFormatter]") one = 0; five[0] = '\0'; kvp.clear(); - f.write(fh, (time_t)2345678901); + f.write(fh, (time_t)2145678903); f.finalize_output(fh); auto size = ftell(fh); diff --git a/src/service_inspectors/cip/CMakeLists.txt b/src/service_inspectors/cip/CMakeLists.txt index 4ca03de26..1ac317fbb 100644 --- a/src/service_inspectors/cip/CMakeLists.txt +++ b/src/service_inspectors/cip/CMakeLists.txt @@ -10,7 +10,6 @@ set( FILE_LIST cip_parsing.h cip_session.cc cip_session.h - cip_util.h ips_cip_attribute.cc ips_cip_class.cc ips_cip_connpathclass.cc diff --git a/src/service_inspectors/cip/cip_parsing.cc b/src/service_inspectors/cip/cip_parsing.cc index 34f1a133b..9b6e0c9fa 100644 --- a/src/service_inspectors/cip/cip_parsing.cc +++ b/src/service_inspectors/cip/cip_parsing.cc @@ -28,10 +28,10 @@ #include "cip_parsing.h" #include "framework/data_bus.h" +#include "utils/endian.h" #include "cip.h" #include "cip_session.h" // For CIP connection tracking -#include "cip_util.h" // For GetLEUint16/32 using namespace snort; @@ -183,14 +183,14 @@ static bool parse_enip_header(const uint8_t* data, #define ENIP_HEADER_OFFSET_CONTEXT 12 #define ENIP_HEADER_OFFSET_OPTIONS 20 - enip_header->command = GetLEUint16(&data[ENIP_HEADER_OFFSET_COMMAND]); - enip_header->length = GetLEUint16(&data[ENIP_HEADER_OFFSET_LENGTH]); - enip_header->session_handle = GetLEUint32(&data[ENIP_HEADER_OFFSET_HANDLE]); - enip_header->status = GetLEUint32(&data[ENIP_HEADER_OFFSET_STATUS]); + enip_header->command = LETOHS(&data[ENIP_HEADER_OFFSET_COMMAND]); + enip_header->length = LETOHS(&data[ENIP_HEADER_OFFSET_LENGTH]); + enip_header->session_handle = LETOHL(&data[ENIP_HEADER_OFFSET_HANDLE]); + enip_header->status = LETOHL(&data[ENIP_HEADER_OFFSET_STATUS]); memcpy(&enip_header->sender_context, &data[ENIP_HEADER_OFFSET_CONTEXT], sizeof(enip_header->sender_context)); - enip_header->options = GetLEUint32(&data[ENIP_HEADER_OFFSET_OPTIONS]); + enip_header->options = LETOHL(&data[ENIP_HEADER_OFFSET_OPTIONS]); if (!enip_command_valid(enip_header->command)) { @@ -345,7 +345,7 @@ static CipMessageType get_cip_message_type(CipCurrentData* current_data, if (enip_cpf->item_list[CPF_ADDRESS_ITEM_SLOT].length > 0) { - uint32_t connection_id = GetLEUint32(enip_cpf->item_list[CPF_ADDRESS_ITEM_SLOT].data); + uint32_t connection_id = LETOHL(enip_cpf->item_list[CPF_ADDRESS_ITEM_SLOT].data); // Validate connected messages against CIP Connection List. CipConnection* connection = cip_find_connection_by_id( @@ -403,7 +403,7 @@ static bool parse_common_packet_format(const uint8_t* data, #define CPF_ITEM_OFFSET_LENGTH 2 #define CPF_ITEM_OFFSET_DATA 4 - enip_cpf->item_count = GetLEUint16(&data[CPF_OFFSET_ITEM_COUNT]); + enip_cpf->item_count = LETOHS(&data[CPF_OFFSET_ITEM_COUNT]); data_length -= CPF_ITEM_COUNT_SIZE; bool valid = true; @@ -424,8 +424,8 @@ static bool parse_common_packet_format(const uint8_t* data, break; } - item_type = GetLEUint16(&data[current_item_offset + CPF_ITEM_OFFSET_TYPE]); - item_length = GetLEUint16(&data[current_item_offset + CPF_ITEM_OFFSET_LENGTH]); + item_type = LETOHS(&data[current_item_offset + CPF_ITEM_OFFSET_TYPE]); + item_length = LETOHS(&data[current_item_offset + CPF_ITEM_OFFSET_LENGTH]); item_data = nullptr; if (item_length > 0) { @@ -516,11 +516,11 @@ static void parse_connection_parameters(const uint8_t* data, #define OFFSET_RPI 0 #define OFFSET_NETWORK_PARAMETERS 4 - connection_parameters->rpi = GetLEUint32(&data[OFFSET_RPI]); + connection_parameters->rpi = LETOHL_UNALIGNED(&data[OFFSET_RPI]); if (!large_forward_open) { - uint16_t network_connection_parameters = GetLEUint16(&data[OFFSET_NETWORK_PARAMETERS]); + uint16_t network_connection_parameters = LETOHS(&data[OFFSET_NETWORK_PARAMETERS]); connection_parameters->network_connection_parameters = network_connection_parameters; if ((network_connection_parameters & NULL_CONNECTION_TYPE_MASK) == 0) @@ -530,7 +530,7 @@ static void parse_connection_parameters(const uint8_t* data, } else // SERVICE_LARGE_FORWARD_OPEN { - uint32_t network_connection_parameters = GetLEUint32(&data[OFFSET_NETWORK_PARAMETERS]); + uint32_t network_connection_parameters = LETOHL(&data[OFFSET_NETWORK_PARAMETERS]); connection_parameters->network_connection_parameters = network_connection_parameters; if ((network_connection_parameters & LARGE_NULL_CONNECTION_TYPE_MASK) == 0) @@ -548,9 +548,9 @@ static void parse_connection_signature(const uint8_t* data, #define OFFSET_VENDOR 2 #define OFFSET_ORIGINATOR_SERIAL 4 - connection_signature->connection_serial_number = GetLEUint16(&data[OFFSET_CONNECTION_SERIAL]); - connection_signature->vendor_id = GetLEUint16(&data[OFFSET_VENDOR]); - connection_signature->originator_serial_number = GetLEUint32(&data[OFFSET_ORIGINATOR_SERIAL]); + connection_signature->connection_serial_number = LETOHS(&data[OFFSET_CONNECTION_SERIAL]); + connection_signature->vendor_id = LETOHS(&data[OFFSET_VENDOR]); + connection_signature->originator_serial_number = LETOHL(&data[OFFSET_ORIGINATOR_SERIAL]); } static bool parse_segment_electronic_key(const uint8_t* data, @@ -765,7 +765,7 @@ static bool parse_segment_port(const uint8_t* data, extended_port_offset += sizeof(uint8_t); } - port_number = GetLEUint16(&data[extended_port_offset]); + port_number = LETOHS(&data[extended_port_offset]); } segment->port_id = port_number; @@ -1147,10 +1147,10 @@ static bool parse_logical_address_format(const uint8_t* data, switch (segment_type & CIP_PATH_LOGICAL_FORMAT_MASK) { case CIP_PATH_LOGICAL_32_BIT: - logical_value = GetLEUint32(&data[data_offset]); + logical_value = LETOHL(&data[data_offset]); break; case CIP_PATH_LOGICAL_16_BIT: - logical_value = GetLEUint16(&data[data_offset]); + logical_value = LETOHS(&data[data_offset]); break; case CIP_PATH_LOGICAL_8_BIT: logical_value = data[data_offset]; @@ -1300,9 +1300,9 @@ static bool parse_forward_open_response_success(const uint8_t* data, #define FWD_OPEN_OFFSET_REPLY_SIZE 24 forward_open_response->connection_pair.ot_connection_id - = GetLEUint32(&data[FWD_OPEN_OFFSET_OT_CONNECTION]); + = LETOHL(&data[FWD_OPEN_OFFSET_OT_CONNECTION]); forward_open_response->connection_pair.to_connection_id - = GetLEUint32(&data[FWD_OPEN_OFFSET_TO_CONNECTION]); + = LETOHL(&data[FWD_OPEN_OFFSET_TO_CONNECTION]); parse_connection_signature(&data[FWD_OPEN_OFFSET_CON_SIGNATURE], &forward_open_response->connection_signature); forward_open_response->application_reply_size @@ -1467,7 +1467,7 @@ static bool parse_multiple_service_packet(const uint8_t* data, // Check that offset data starts after the last offset. data_offset = CIP_MSP_NUMBER_SERVICES_FIELD_SIZE + total_offset_size; - first_offset = GetLEUint16(&data[CIP_MSP_NUMBER_SERVICES_FIELD_SIZE]); + first_offset = LETOHS(&data[CIP_MSP_NUMBER_SERVICES_FIELD_SIZE]); if (first_offset < data_offset) { return false; @@ -1487,7 +1487,7 @@ static bool parse_multiple_service_packet(const uint8_t* data, uint16_t buffer_offset = i * CIP_MSP_OFFSET_FIELD_SIZE; /* This if the offset from the Number of Services field to the data. */ - size_t msp_offset = GetLEUint16(&data[buffer_offset]); + size_t msp_offset = LETOHS(&data[buffer_offset]); /* There is no end offset specified, so the next offset needs checked to find the length of the current service. For the last packet, @@ -1500,7 +1500,7 @@ static bool parse_multiple_service_packet(const uint8_t* data, else { uint16_t next_buffer_offset = buffer_offset + CIP_MSP_OFFSET_FIELD_SIZE; - msp_offset_end = GetLEUint16(&data[next_buffer_offset]); + msp_offset_end = LETOHS(&data[next_buffer_offset]); } // Check that offsets are increasing. @@ -1563,7 +1563,7 @@ static bool parse_unconnected_send_request(const uint8_t* data, cip_request->has_timeout = true; #define UNCONNECTED_SEND_OFFSET_MESSAGE_SIZE 2 - message_request_size = GetLEUint16(&data[UNCONNECTED_SEND_OFFSET_MESSAGE_SIZE]); + message_request_size = LETOHS(&data[UNCONNECTED_SEND_OFFSET_MESSAGE_SIZE]); data += UNCONNECTED_SEND_HEADER_SIZE; data_length -= UNCONNECTED_SEND_HEADER_SIZE; @@ -1906,7 +1906,7 @@ static bool parse_enip_command_data(const uint8_t* data, // Interface Handle #define ENIP_OFFSET_INTERFACE_HANDLE 0 - interface_handle = GetLEUint32(&data[ENIP_OFFSET_INTERFACE_HANDLE]); + interface_handle = LETOHL(&data[ENIP_OFFSET_INTERFACE_HANDLE]); #define CIP_INTERFACE_HANDLE 0 if (interface_handle != CIP_INTERFACE_HANDLE) diff --git a/src/service_inspectors/cip/cip_util.h b/src/service_inspectors/cip/cip_util.h deleted file mode 100644 index 42f024872..000000000 --- a/src/service_inspectors/cip/cip_util.h +++ /dev/null @@ -1,51 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -// cip_util.h author RA/Cisco - -/* Description: Common utility functions. */ - -#ifndef CIP_UTIL_H -#define CIP_UTIL_H - -#include // For endian checks - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -// Get 16-bit value from little endian byte array. -static inline uint16_t GetLEUint16(const uint8_t* pData) -{ - return (static_cast(*(pData + 1) << 8) - | static_cast(*(pData + 0) << 0)); -} - -// Get 32-bit value from little endian byte array. -static inline uint32_t GetLEUint32(const uint8_t* pData) -{ - return (static_cast(*(pData + 3) << 24) - | static_cast(*(pData + 2) << 16) - | static_cast(*(pData + 1) << 8) - | static_cast(*(pData + 0) << 0)); -} - -#else // __BYTE_ORDER -#error "CIP Preprocessor is only supported on Little Endian." -#endif // __BYTE_ORDER - -#endif /* CIP_UTIL_H */ - diff --git a/src/utils/endian.h b/src/utils/endian.h index 5fe9572af..8bf5da743 100644 --- a/src/utils/endian.h +++ b/src/utils/endian.h @@ -28,6 +28,8 @@ #ifdef __FreeBSD__ # include +# define bswap_16(a) bswap16(a) +# define bswap_32(a) bswap32(a) # define bswap_64(a) bswap64(a) #endif @@ -40,4 +42,22 @@ # define ntohll(a) ( 1 == ntohl(1) ? (a) : bswap_64(a) ) #endif +#if defined(WORDS_BIGENDIAN) +#define LETOHS(p) bswap_16(*((const uint16_t*)(p))) +#define LETOHL(p) bswap_32(*((const uint32_t*)(p))) +#else +#define LETOHS(p) (*((const uint16_t*)(p))) +#define LETOHL(p) (*((const uint32_t*)(p))) +#endif + +#define LETOHS_UNALIGNED(p) \ + ((uint16_t)(*((const uint8_t*)(p) + 1) << 8) | \ + (uint16_t)(*((const uint8_t*)(p)))) + +#define LETOHL_UNALIGNED(p) \ + ((uint32_t)(*((const uint8_t*)(p) + 3) << 24) | \ + (uint32_t)(*((const uint8_t*)(p) + 2) << 16) | \ + (uint32_t)(*((const uint8_t*)(p) + 1) << 8) | \ + (uint32_t)(*((const uint8_t*)(p)))) + #endif