]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1954 in SNORT/snort3 from ~OKHOMIAK/snort3:big_endian_system_buil...
authorSteve Chew (stechew) <stechew@cisco.com>
Tue, 25 Feb 2020 19:06:51 +0000 (19:06 +0000)
committerSteve Chew (stechew) <stechew@cisco.com>
Tue, 25 Feb 2020 19:06:51 +0000 (19:06 +0000)
Squashed commit of the following:

commit d402a299c4168f67eea200fc0e5973071a6bc5c1
Author: Oleksii Khomiakovskyi <okhomiak@cisco.com>
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

13 files changed:
src/codecs/ip/cd_ipv4.cc
src/connectors/tcp_connector/test/tcp_connector_test.cc
src/flow/test/flow_cache_test.cc
src/host_tracker/test/host_cache_test.cc
src/network_inspectors/appid/appid_detector.h
src/network_inspectors/appid/service_plugins/service_netbios.cc
src/network_inspectors/perf_monitor/cpu_tracker.cc
src/network_inspectors/perf_monitor/csv_formatter.cc
src/network_inspectors/perf_monitor/json_formatter.cc
src/service_inspectors/cip/CMakeLists.txt
src/service_inspectors/cip/cip_parsing.cc
src/service_inspectors/cip/cip_util.h [deleted file]
src/utils/endian.h

index c61ef98d2c952242636bfe9fcc59a8c134417635..a4f2b1835744a3b314bbc7c0c916465ef1ccadce 100644 (file)
@@ -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);
index 5ec7fb82f9625836f4be2a159843d364373d1f24..51f4abfb5b98c04d3de3d5307e27d6f2462bd965 100644 (file)
@@ -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;
index 411044b85f8fe4501049def1e96ac1e9ab568c3a..21f7e77641f0869fdbfb6c1a3303521392f9c013 100644 (file)
@@ -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; }
 }
 
index 2a2ba347c59a95860374ddd864fd526f4caa24e4..cad83895f6dc43a1e06dd0ca4b6a1a52a1963994 100644 (file)
@@ -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)
index 617f9849248437012da5eb84b657ffc23666ab62..2f22f0ea4e918bfb325fc8c327d930c03dbb5841 100644 (file)
@@ -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
 
index 9ffef77e9d2ecd6a943a46b61c0d81de13aaa9d5..e4579d93f66b6332b975c1658d48db2f79e440eb 100644 (file)
 
 #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:
index 7c3c2dab519f9f360d7b614ae59a132a40ebe1e7..6427e8574055ae1660e7d1bb638b25e3979c13d5 100644 (file)
@@ -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<std::int32_t>::max();
     t.tv_usec = 999999;
     auto ms = get_microseconds(t);
     t2.tv_sec = ms / 1000000;
index c4da5d1a65b33ad87461678681fdeccc4a6a33bb..aa291ddbff68f95946b91e83ce8a51fbc0300b90 100644 (file)
@@ -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];
index 2d25ea1222295a90312aa02a601b4036293aa925..313e5ef98c1260ae439cd4ca0597b119b35c0cdc 100644 (file)
@@ -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);
index 4ca03de26543657e60b0d7f5629f4143fc6ad4ac..1ac317fbb55a8311f752285634a382399ce30ac1 100644 (file)
@@ -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  
index 34f1a133b629795c38bba8a9beeb96f509d93433..9b6e0c9faef7f73e6900b29e72cb51525e027b45 100644 (file)
 #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 (file)
index 42f0248..0000000
+++ /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 <sys/types.h>  // 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<uint16_t>(*(pData + 1) << 8)
-           | static_cast<uint16_t>(*(pData + 0) << 0));
-}
-
-// Get 32-bit value from little endian byte array.
-static inline uint32_t GetLEUint32(const uint8_t* pData)
-{
-    return (static_cast<uint32_t>(*(pData + 3) << 24)
-           | static_cast<uint32_t>(*(pData + 2) << 16)
-           | static_cast<uint32_t>(*(pData + 1) << 8)
-           | static_cast<uint32_t>(*(pData + 0) << 0));
-}
-
-#else  // __BYTE_ORDER
-#error "CIP Preprocessor is only supported on Little Endian."
-#endif  // __BYTE_ORDER
-
-#endif  /* CIP_UTIL_H */
-
index 5fe9572aff3f47e6d69f76ab4b2c97bb89bdcaf0..8bf5da743aa52b9afd4ff78f4e57bb77cc6027b0 100644 (file)
@@ -28,6 +28,8 @@
 
 #ifdef __FreeBSD__
 # include <sys/endian.h>
+# define bswap_16(a) bswap16(a)
+# define bswap_32(a) bswap32(a)
 # define bswap_64(a) bswap64(a)
 #endif
 
 # 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