From: Russ Combs (rucombs) Date: Mon, 27 Feb 2017 21:19:10 +0000 (-0500) Subject: Merge pull request #827 in SNORT/snort3 from byte_order to master X-Git-Tag: 3.0.0-233~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=699c504f1c8d0d887ad0f9ed226cd683021f82d3;p=thirdparty%2Fsnort3.git Merge pull request #827 in SNORT/snort3 from byte_order to master Squashed commit of the following: commit a257b0dafc53321b199b7e5100d700345e133e32 Author: Russ Combs Date: Sat Feb 25 10:16:15 2017 -0500 add multiple byte orders warning --- diff --git a/src/framework/endianness.h b/src/framework/endianness.h index 5dd2aa9e5..73e8c4159 100644 --- a/src/framework/endianness.h +++ b/src/framework/endianness.h @@ -28,7 +28,7 @@ class SO_PUBLIC Endianness public: Endianness() = default; virtual ~Endianness() { } - virtual bool get_offset_endianness(int32_t offset, int8_t& endian) = 0; + virtual bool get_offset_endianness(int32_t offset, uint8_t& endian) = 0; }; #endif diff --git a/src/ips_options/extract.cc b/src/ips_options/extract.cc index 434efd9cc..bf5961d9a 100644 --- a/src/ips_options/extract.cc +++ b/src/ips_options/extract.cc @@ -25,9 +25,18 @@ #include "extract.h" +#include "log/messages.h" #include "utils/snort_bounds.h" #include "utils/util_cstring.h" +void set_byte_order(uint8_t& order, uint8_t flag, const char* opt) +{ + if ( order ) + ParseWarning(WARN_RULES, "%s specifies multiple byte orders, using last", opt); + + order = flag; +} + #define TEXTLEN (PARSELEN + 1) /** diff --git a/src/ips_options/extract.h b/src/ips_options/extract.h index a435cdcea..f4f177e8e 100644 --- a/src/ips_options/extract.h +++ b/src/ips_options/extract.h @@ -22,9 +22,9 @@ #include "main/snort_types.h" -#define ENDIAN_BIG 0x0 -#define ENDIAN_LITTLE 0x1 -#define ENDIAN_FUNC 0x2 +#define ENDIAN_BIG 0x1 +#define ENDIAN_LITTLE 0x2 +#define ENDIAN_FUNC 0x4 #define PARSELEN 10 @@ -36,5 +36,7 @@ SO_PUBLIC int byte_extract( int endianess, int bytes_to_grab, const uint8_t* ptr, const uint8_t* start, const uint8_t* end, uint32_t* value); +SO_PUBLIC void set_byte_order(uint8_t& order, uint8_t flag, const char* opt); + #endif diff --git a/src/ips_options/ips_byte_extract.cc b/src/ips_options/ips_byte_extract.cc index d2f8678f4..de74f076d 100644 --- a/src/ips_options/ips_byte_extract.cc +++ b/src/ips_options/ips_byte_extract.cc @@ -54,7 +54,7 @@ struct ByteExtractData uint8_t relative_flag; uint8_t data_string_convert_flag; uint8_t align; - int8_t endianess; + uint8_t endianess; uint32_t base; uint32_t multiplier; int8_t var_number; @@ -166,7 +166,7 @@ int ByteExtractOption::eval(Cursor& c, Packet* p) if (ptr < start || ptr >= end) return DETECTION_OPTION_NO_MATCH; - int8_t endian = data->endianess; + uint8_t endian = data->endianess; if (data->endianess == ENDIAN_FUNC) { if (!p->endianness || @@ -359,16 +359,6 @@ static bool ByteExtractVerify(ByteExtractData* data) "argument."); return false; } - unsigned e1 = ffs(data->endianess); - unsigned e2 = ffs(data->endianess >> e1); - - if ( e1 && e2 ) - { - ParseError("byte_extract rule option has multiple arguments " - "specifying endianness. Use only " - "one of 'big', 'little', or 'dce'."); - return false; - } return true; } @@ -444,6 +434,8 @@ bool ExtractModule::begin(const char*, int, SnortConfig*) bool ExtractModule::end(const char*, int, SnortConfig*) { + if ( !data.endianess ) + data.endianess = ENDIAN_BIG; return ByteExtractVerify(&data); } @@ -468,13 +460,13 @@ bool ExtractModule::set(const char*, Value& v, SnortConfig*) data.multiplier = v.get_long(); else if ( v.is("big") ) - data.endianess |= ENDIAN_BIG; + set_byte_order(data.endianess, ENDIAN_BIG, "byte_extract"); else if ( v.is("little") ) - data.endianess |= ENDIAN_LITTLE; + set_byte_order(data.endianess, ENDIAN_LITTLE, "byte_extract"); else if ( v.is("dce") ) - data.endianess |= ENDIAN_FUNC; + set_byte_order(data.endianess, ENDIAN_FUNC, "byte_extract"); else if ( v.is("string") ) { diff --git a/src/ips_options/ips_byte_jump.cc b/src/ips_options/ips_byte_jump.cc index 0a6390eb6..f6a1d9fc8 100644 --- a/src/ips_options/ips_byte_jump.cc +++ b/src/ips_options/ips_byte_jump.cc @@ -93,7 +93,7 @@ typedef struct _ByteJumpData uint8_t data_string_convert_flag; uint8_t from_beginning_flag; uint8_t align_flag; - int8_t endianess; + uint8_t endianess; uint32_t base; uint32_t multiplier; int32_t post_offset; @@ -213,7 +213,7 @@ int ByteJumpOption::eval(Cursor& c, Packet* p) uint32_t jump = 0; uint32_t payload_bytes_grabbed = 0; - int8_t endian = bjd->endianess; + uint8_t endian = bjd->endianess; if (endian == ENDIAN_FUNC) { if (!p->endianness || @@ -368,16 +368,8 @@ bool ByteJumpModule::end(const char*, int, SnortConfig*) return false; } } - unsigned e1 = ffs(data.endianess); - unsigned e2 = ffs(data.endianess >> e1); - - if ( e1 && e2 ) - { - ParseError("byte_jump has multiple arguments " - "specifying endianness. Use only " - "one of 'big', 'little', or 'dce'."); - return false; - } + if ( !data.endianess ) + data.endianess = ENDIAN_BIG; return true; } @@ -411,13 +403,13 @@ bool ByteJumpModule::set(const char*, Value& v, SnortConfig*) data.post_offset = v.get_long(); else if ( v.is("big") ) - data.endianess |= ENDIAN_BIG; + set_byte_order(data.endianess, ENDIAN_BIG, "byte_jump"); else if ( v.is("little") ) - data.endianess |= ENDIAN_LITTLE; + set_byte_order(data.endianess, ENDIAN_LITTLE, "byte_jump"); else if ( v.is("dce") ) - data.endianess |= ENDIAN_FUNC; + set_byte_order(data.endianess, ENDIAN_FUNC, "byte_jump"); else if ( v.is("string") ) { diff --git a/src/ips_options/ips_byte_test.cc b/src/ips_options/ips_byte_test.cc index 75751196a..ed64251dd 100644 --- a/src/ips_options/ips_byte_test.cc +++ b/src/ips_options/ips_byte_test.cc @@ -132,7 +132,7 @@ typedef struct _ByteTestData uint8_t not_flag; uint8_t relative_flag; uint8_t data_string_convert_flag; - int8_t endianess; + uint8_t endianess; uint32_t base; int8_t cmp_value_var; int8_t offset_var; @@ -312,7 +312,7 @@ int ByteTestOption::eval(Cursor& c, Packet* p) const uint8_t* start_ptr = btd->relative_flag ? c.start() : c.buffer(); start_ptr += offset; - int8_t endian = btd->endianess; + uint8_t endian = btd->endianess; if (endian == ENDIAN_FUNC) { if (!p->endianness || @@ -514,16 +514,8 @@ bool ByteTestModule::end(const char*, int, SnortConfig*) return false; } } - unsigned e1 = ffs(data.endianess); - unsigned e2 = ffs(data.endianess >> e1); - - if ( e1 && e2 ) - { - ParseError("byte_test has multiple arguments " - "specifying endianness. Use only " - "one of 'big', 'little', or 'dce'."); - return false; - } + if ( !data.endianess ) + data.endianess = ENDIAN_BIG; return true; } @@ -556,13 +548,13 @@ bool ByteTestModule::set(const char*, Value& v, SnortConfig*) data.relative_flag = 1; else if ( v.is("big") ) - data.endianess |= ENDIAN_BIG; + set_byte_order(data.endianess, ENDIAN_BIG, "byte_test"); else if ( v.is("little") ) - data.endianess |= ENDIAN_LITTLE; + set_byte_order(data.endianess, ENDIAN_LITTLE, "byte_test"); else if ( v.is("dce") ) - data.endianess |= ENDIAN_FUNC; + set_byte_order(data.endianess, ENDIAN_FUNC, "byte_test"); else if ( v.is("string") ) { diff --git a/src/service_inspectors/dce_rpc/dce_common.cc b/src/service_inspectors/dce_rpc/dce_common.cc index cca068957..9b2e8c39e 100644 --- a/src/service_inspectors/dce_rpc/dce_common.cc +++ b/src/service_inspectors/dce_rpc/dce_common.cc @@ -267,7 +267,7 @@ void DceEndianness::reset() stub_data_offset = DCE2_SENTINEL; } -bool DceEndianness::get_offset_endianness(int32_t offset, int8_t& endian) +bool DceEndianness::get_offset_endianness(int32_t offset, uint8_t& endian) { int byte_order; diff --git a/src/service_inspectors/dce_rpc/dce_common.h b/src/service_inspectors/dce_rpc/dce_common.h index 1d0e009cd..e815f79ad 100644 --- a/src/service_inspectors/dce_rpc/dce_common.h +++ b/src/service_inspectors/dce_rpc/dce_common.h @@ -221,7 +221,7 @@ public: public: DceEndianness(); - virtual bool get_offset_endianness(int32_t offset, int8_t& endian); + virtual bool get_offset_endianness(int32_t offset, uint8_t& endian); void reset(); };