From 91407e0938f29574acdcf70ea924ada739819d11 Mon Sep 17 00:00:00 2001 From: Gurvinder Singh Date: Tue, 24 Nov 2009 19:28:52 +0530 Subject: [PATCH] fixed DetectByteTest bug --- src/detect-bytetest.c | 62 ++++++++++++++++++++++++------------------- src/util-byte.c | 36 ++++++++++++++++--------- src/util-error.c | 6 ++++- src/util-error.h | 5 ++++ 4 files changed, 69 insertions(+), 40 deletions(-) diff --git a/src/detect-bytetest.c b/src/detect-bytetest.c index 52ff567afa..98cb81c8c3 100644 --- a/src/detect-bytetest.c +++ b/src/detect-bytetest.c @@ -51,14 +51,15 @@ void DetectBytetestRegister (void) { parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); if(parse_regex == NULL) { - printf("DetectBytetestRegister: pcre compile of \"%s\" failed at offset %" PRId32 ": %s\n", PARSE_REGEX, eo, eb); + SCLogError(SC_PCRE_COMPILE_FAILED, "pcre compile of \"%s\" failed at " + "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); goto error; } parse_regex_study = pcre_study(parse_regex, 0, &eb); if(eb != NULL) { - printf("DetectBytetestRegister: pcre study failed: %s\n", eb); + SCLogError(SC_PCRE_STUDY_FAILED, "pcre study failed: %s", eb); goto error; } return; @@ -107,9 +108,8 @@ int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, * \todo Should this validate it is in the *payload*? */ if ((ptr < p->pkt) || (len < 0) || (data->nbytes > len)) { - printf("DetectBytetestMatch: Data not within packet " - "pkt=%p, ptr=%p, len=%d, nbytes=%d\n", - p->pkt, ptr, len, data->nbytes); + SCLogDebug("Data not within packet pkt=%p, ptr=%p, len=%d, nbytes=%d", + p->pkt, ptr, len, data->nbytes); return 0; } @@ -119,20 +119,27 @@ int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, if (data->flags & DETECT_BYTETEST_STRING) { extbytes = ByteExtractStringUint64(&val, data->base, data->nbytes, (const char *)ptr); - if(extbytes <= 0) { - printf("DetectBytetestMatch: Error extracting %d " - "bytes of string data: %d\n", data->nbytes, extbytes); - return -1; + if (extbytes <= 0) { + /* strtoull() return 0 if there is no numeric value in data string */ + if (val == 0) { + SCLogDebug("No Numeric value"); + return 0; + } else { + SCLogError(SC_INVALID_NUM_BYTES, "Error extracting %d " + "bytes of string data: %d", data->nbytes, extbytes); + return -1; + } } SCLogDebug("comparing base %d string 0x%" PRIx64 " %s%c 0x%" PRIx64 "", data->base, val, (neg ? "!" : ""), data->op, data->value); } else { - int endianness = (data->flags & DETECT_BYTETEST_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN; + int endianness = (data->flags & DETECT_BYTETEST_LITTLE) ? + BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN; extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr); if (extbytes != data->nbytes) { - printf("DetectBytetestMatch: Error extracting %d bytes " + SCLogError(SC_INVALID_NUM_BYTES, "Error extracting %d bytes " "of numeric data: %d\n", data->nbytes, extbytes); return -1; } @@ -203,16 +210,16 @@ DetectBytetestData *DetectBytetestParse(char *optstr) ret = pcre_exec(parse_regex, parse_regex_study, optstr, strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret < 6 || ret > 10) { - printf("DetectBytetestParse: parse error, ret %" PRId32 - ", string %s\n", ret, optstr); + SCLogError(SC_PCRE_PARSE_FAILED, "parse error, ret %" PRId32 + ", string %s", ret, optstr); goto error; } for (i = 0; i < (ret - 1); i++) { res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS, i + 1, &str_ptr); if (res < 0) { - printf("DetectBytetestParse: pcre_get_substring failed " - "for arg %d\n", i + 1); + SCLogError(SC_PCRE_GET_SUBSTRING_FAILED, "pcre_get_substring failed " + "for arg %d", i + 1); goto error; } args[i] = (char *)str_ptr; @@ -221,7 +228,7 @@ DetectBytetestData *DetectBytetestParse(char *optstr) /* Initialize the data */ data = malloc(sizeof(DetectBytetestData)); if (data == NULL) { - printf("DetectBytetestParse: malloc failed\n"); + SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); goto error; } data->base = DETECT_BYTETEST_BASE_UNSET; @@ -235,7 +242,7 @@ DetectBytetestData *DetectBytetestParse(char *optstr) /* Number of bytes */ if (ByteExtractStringUint32(&nbytes, 10, 0, args[0]) <= 0) { - printf("DetectBytetestParse: Malformed number of bytes: %s\n", str_ptr); + SCLogDebug("Malformed number of bytes: %s", str_ptr); goto error; } @@ -244,7 +251,9 @@ DetectBytetestData *DetectBytetestParse(char *optstr) if (*args[1] == '!') { data->flags |= DETECT_BYTETEST_NEGOP; } - if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP) && strcmp("", args[2]) == 0)) { + if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP) + && strcmp("", args[2]) == 0)) + { data->op |= DETECT_BYTETEST_OP_EQ; } else if (strcmp("<", args[2]) == 0) { data->op |= DETECT_BYTETEST_OP_LT; @@ -261,13 +270,13 @@ DetectBytetestData *DetectBytetestParse(char *optstr) /* Value */ if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) { - printf("DetectBytetestParse: Malformed value: %s\n", str_ptr); + SCLogDebug("Malformed value: %s", str_ptr); goto error; } /* Offset */ if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) { - printf("DetectBytetestParse: Malformed offset: %s\n", str_ptr); + SCLogDebug(" Malformed offset: %s", str_ptr); goto error; } @@ -292,7 +301,7 @@ DetectBytetestData *DetectBytetestParse(char *optstr) } else if (strcasecmp("little", args[i]) == 0) { data->flags |= DETECT_BYTETEST_LITTLE; } else { - printf("DetectBytetestParse: Unknown option: \"%s\"\n", args[i]); + SCLogDebug("Unknown option: \"%s\"", args[i]); goto error; } } @@ -306,19 +315,18 @@ DetectBytetestData *DetectBytetestParse(char *optstr) * "01777777777777777777777" = 0xffffffffffffffff */ if (nbytes > 23) { - printf("DetectBytetestParse: Cannot test more than " - "23 bytes with \"string\": %s\n", optstr); + SCLogDebug("Cannot test more than 23 bytes with \"string\": %s", + optstr); goto error; } } else { if (nbytes > 8) { - printf("DetectBytetestParse: Cannot test more than " - "8 bytes without \"string\": %s\n", optstr); + SCLogDebug("Cannot test more than 8 bytes without \"string\": %s", + optstr); goto error; } if (data->base != DETECT_BYTETEST_BASE_UNSET) { - printf("DetectBytetestParse: Cannot use a base " - "without \"string\": %s\n", optstr); + SCLogDebug("Cannot use a base without \"string\": %s", optstr); goto error; } } diff --git a/src/util-byte.c b/src/util-byte.c index d903811a44..7c4016f1e8 100644 --- a/src/util-byte.c +++ b/src/util-byte.c @@ -1,6 +1,7 @@ #include "eidps-common.h" #include "util-byte.h" #include "util-unittest.h" +#include "util-debug.h" /** \todo: Remove the fprintf errors in favor of logging */ @@ -112,7 +113,7 @@ int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) char strbuf[24]; if (len > 23) { - fprintf(stderr, "ByteExtractString: len too large (23 max)\n"); + SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)"); return -1; } @@ -127,10 +128,15 @@ int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) *res = strtoull(ptr, &endptr, base); if (errno == ERANGE) { - fprintf(stderr, "ByteExtractString: Numeric value out of range\n"); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); return -1; } else if (endptr == str) { - fprintf(stderr, "ByteExtractString: Invalid numeric value\n"); + SCLogError(SC_INVALID_NUMERIC_VALUE, "Invalid numeric value"); + return -1; + /* If there is no numeric value in the given string then strtoull(), makes + endptr equals to ptr and return 0 as result */ + } else if (endptr == ptr && *res == 0) { + SCLogDebug("No numeric value"); return -1; } /* This will interfere with some rules that do not know the length @@ -164,7 +170,8 @@ inline int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const *res = (uint32_t)i64; if ((uint64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64); return -1; } @@ -184,7 +191,8 @@ inline int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const *res = (uint16_t)i64; if ((uint64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringUint16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64); return -1; } @@ -204,7 +212,8 @@ inline int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const ch *res = (uint8_t)i64; if ((uint64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringUint8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (uint64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64); return -1; } @@ -226,7 +235,7 @@ int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *st char strbuf[24]; if (len > 23) { - fprintf(stderr, "ByteExtractStringSigned: len too large (23 max)\n"); + SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)"); return -1; } @@ -241,10 +250,10 @@ int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *st *res = strtoll(ptr, &endptr, base); if (errno == ERANGE) { - fprintf(stderr, "ByteExtractStringSigned: Numeric value out of range\n"); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); return -1; } else if (endptr == str) { - fprintf(stderr, "ByteExtractStringSigned: Invalid numeric value\n"); + SCLogError(SC_INVALID_NUMERIC_VALUE, "Invalid numeric value"); return -1; } /* This will interfere with some rules that do not know the length @@ -280,7 +289,8 @@ inline int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const ch *res = (int32_t)i64; if ((int64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringUint32: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; } @@ -300,7 +310,8 @@ inline int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const ch *res = (int16_t)i64; if ((int64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringInt16: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; } @@ -320,7 +331,8 @@ inline int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *res = (int8_t)i64; if ((int64_t)(*res) != i64) { - fprintf(stderr, "ByteExtractStringInt8: Numeric value out of range (%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); + SCLogError(SC_NUMERIC_VALUE_ERANGE, "Numeric value out of range " + "(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64); return -1; } diff --git a/src/util-error.c b/src/util-error.c index ce3a19e294..806ae961ab 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -22,6 +22,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_PCRE_GET_SUBSTRING_FAILED); CASE_CODE (SC_PCRE_COMPILE_FAILED); CASE_CODE (SC_PCRE_STUDY_FAILED); + CASE_CODE (SC_PCRE_PARSE_FAILED); CASE_CODE (SC_LOG_MODULE_NOT_INIT); CASE_CODE (SC_LOG_FG_FILTER_MATCH_FAILED); CASE_CODE (SC_COUNTER_EXCEEDED); @@ -38,7 +39,10 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_NEGATED_VALUE_IN_PORT_RANGE); CASE_CODE (SC_PORT_PARSE_INSERT_STRING_ERR); CASE_CODE (SC_UNREACHABLE_CODE_REACHED); - + CASE_CODE (SC_INVALID_NUMERIC_VALUE); + CASE_CODE (SC_NUMERIC_VALUE_ERANGE); + CASE_CODE (SC_INVALID_NUM_BYTES); + CASE_CODE (SC_ERR_ARG_LEN_LONG); default: return "UNKNOWN_ERROR"; } diff --git a/src/util-error.h b/src/util-error.h index 53b156e1f3..7bc8173f3c 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -14,6 +14,7 @@ typedef enum { SC_PCRE_GET_SUBSTRING_FAILED, SC_PCRE_COMPILE_FAILED, SC_PCRE_STUDY_FAILED, + SC_PCRE_PARSE_FAILED, SC_LOG_MODULE_NOT_INIT, SC_LOG_FG_FILTER_MATCH_FAILED, SC_COUNTER_EXCEEDED, @@ -40,6 +41,10 @@ typedef enum { SC_PORT_PARSE_INSERT_STRING_ERR, SC_UNREACHABLE_CODE_REACHED, SC_ALPARSER_ERR, + SC_INVALID_NUMERIC_VALUE, + SC_NUMERIC_VALUE_ERANGE, + SC_INVALID_NUM_BYTES, + SC_ERR_ARG_LEN_LONG, } SCError; const char *SCErrorToString(SCError);