Under some cases (below), the depth and offset values are used
twice. This commit disregards the distance variable (if any), when
computing the final depth.
These rules are logically equivalent::
1. alert tcp any any -> any 8080 (msg:"distance name"; flow:to_server; content:"Authorization:"; content:"5f71ycy"; distance:0; byte_extract:1,0,option_len,string,relative; content:!"|38|"; distance:option_len; within:1; content:"|37|"; distance:-1; within:1; content:"|49|"; distance:option_len; within:1; sid:1;)
2. alert tcp any any -> any 8080 (msg:"distance number"; flow:to_server; content:"Authorization:"; content:"5f71ycy"; distance:0; byte_extract:1,0,option_len,string,relative; content:!"|38|"; distance:7; within:1; content:"|37|"; distance:-1; within:1; content:"|49|"; distance:option_len; within:1; sid:2;)
The differences:
Rule 1: content:!"|38|"; distance:option_len; within:1; //option_len == 7
Rule 2: content:!"|38|"; distance:7; within:1;
Without this commit, rule 2 triggers an alert but rule 1 doesn't.
Issue: 7390
(cherry picked from commit
ace0d3763674a8dc624ad1f1744ea7442cd86d43)
VALIDATE(depth + cd->within + dist >= 0 &&
depth + cd->within + dist <= UINT16_MAX);
depth = cd->depth = (uint16_t)(depth + cd->within + dist);
- } else {
+ } else if ((cd->flags & DETECT_CONTENT_DISTANCE_VAR) == 0) {
+ // we cannot know the depth yet if it comes from a var
SCLogDebug("offset %u + cd->within %u", offset, cd->within);
VALIDATE(depth + cd->within >= 0 && depth + cd->within <= UINT16_MAX);
depth = cd->depth = (uint16_t)(offset + cd->within);
/* If the value came from a variable, make sure to adjust the depth so it's relative
* to the offset value.
*/
- if (cd->flags & (DETECT_CONTENT_DISTANCE_VAR|DETECT_CONTENT_OFFSET_VAR|DETECT_CONTENT_DEPTH_VAR)) {
- depth += offset;
+ if (cd->flags & (DETECT_CONTENT_OFFSET_VAR | DETECT_CONTENT_DEPTH_VAR)) {
+ depth += offset;
}
/* update offset with prev_offset if we're searching for