fixed DetectByteTest bug

remotes/origin/master-1.0.x
Gurvinder Singh 15 years ago committed by Victor Julien
parent 6206ffb530
commit 91407e0938

@ -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;
}
}

@ -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;
}

@ -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";
}

@ -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);

Loading…
Cancel
Save