Skip to content

Commit b044b43

Browse files
committed
Fix header table corruption
We had a bug during the suffix match in function `tfw_http_search_cookie()`, before comparing the name we store current chunk `t = *chunk`, then modify and compare the chunk, after we rostore the chunk `*chunk = t;` that leads to header corruption, because macros `TFW_STR_EQ_CSTR` may assign new address to `chunk`, therefore restoration happens to a newly assigned adress instead of original adress in `chunk`. Fixed by storing address to temporary variable and then restore `data` and `len` by this adress. `__tfw_str_eq_cstr` rewritten to inline function. Inline functions is more clear, less error prone and suitable in this case, because we don't need to define tmp vars and explicitly save values, only move `chunk` pointer forward. Generated assembly will be the same.
1 parent 2464bf3 commit b044b43

File tree

1 file changed

+35
-30
lines changed

1 file changed

+35
-30
lines changed

fw/http_match.c

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,31 @@ tfw_http_verify_hdr_field(tfw_http_match_fld_t field, const char **hdr_name,
876876
return 0;
877877
}
878878

879+
/* Simple version of tfw_str_eq_cstr. */
880+
static bool __always_inline
881+
__tfw_str_eq_cstr(const char *cstr, unsigned long clen, TfwStr **pos,
882+
const TfwStr *end)
883+
{
884+
TfwStr *chunk = *pos;
885+
886+
while (chunk != end) {
887+
int len = min(clen, chunk->len);
888+
889+
if (memcmp_fast(cstr, chunk->data, len))
890+
break;
891+
892+
cstr += len;
893+
clen -= len;
894+
if (!clen)
895+
break;
896+
chunk++;
897+
}
898+
899+
*pos = chunk;
900+
901+
return !clen;
902+
}
903+
879904
/*
880905
* Search for cookie in `Set-Cookie`/`Cookie` header value @cookie
881906
* and save the cookie value into @val.
@@ -902,26 +927,6 @@ tfw_http_search_cookie(const char *cstr, unsigned long clen,
902927
{
903928
TfwStr *chunk;
904929

905-
/* Simple version of tfw_str_eq_cstr. */
906-
#define TFW_STR_EQ_CSTR(end) \
907-
({ \
908-
const char *tmp_cstr = cstr; \
909-
unsigned long tmp_clen = clen; \
910-
\
911-
while (chunk != end) { \
912-
int len = min(tmp_clen, chunk->len); \
913-
if (memcmp_fast(tmp_cstr, chunk->data, len)) \
914-
break; \
915-
\
916-
tmp_cstr += len; \
917-
tmp_clen -= len; \
918-
if (!tmp_clen) \
919-
break; \
920-
chunk++; \
921-
} \
922-
!tmp_clen; \
923-
})
924-
925930
/* Search cookie name. */
926931
for (chunk = *pos; chunk != end; ++chunk) {
927932
if (!(chunk->flags & TFW_STR_NAME))
@@ -933,26 +938,26 @@ tfw_http_search_cookie(const char *cstr, unsigned long clen,
933938
if (op == TFW_HTTP_MATCH_O_PREFIX ||
934939
op == TFW_HTTP_MATCH_O_EQ)
935940
{
936-
if (TFW_STR_EQ_CSTR(end))
941+
if (__tfw_str_eq_cstr(cstr, clen, &chunk, end))
937942
break;
938943
while ((chunk + 1 != end) &&
939944
((chunk + 1)->flags & TFW_STR_NAME))
940945
++chunk;
941946
}
942947
else if (op == TFW_HTTP_MATCH_O_SUFFIX) {
943-
TfwStr *name, t;
944-
unsigned int len = 0, name_n = 0;
948+
TfwStr *name, *orig;
949+
unsigned int len = 0;
945950
ssize_t offset;
946951

947-
for (name = chunk; name != end; ++name, ++name_n) {
952+
for (name = chunk; name != end; ++name) {
948953
if (!(name->flags & TFW_STR_NAME))
949954
break;
950955
len += name->len;
951956
}
952957

953958
offset = len - clen;
954959
if (!offset) {
955-
if (TFW_STR_EQ_CSTR(name))
960+
if (__tfw_str_eq_cstr(cstr, clen, &chunk, name))
956961
break;
957962
} else if (offset > 0) {
958963
bool equal;
@@ -961,11 +966,13 @@ tfw_http_search_cookie(const char *cstr, unsigned long clen,
961966
offset -= chunk->len;
962967
++chunk;
963968
}
964-
t = *chunk;
969+
orig = chunk;
965970
chunk->data += offset;
966971
chunk->len -= offset;
967-
equal = TFW_STR_EQ_CSTR(name);
968-
*chunk = t;
972+
equal = __tfw_str_eq_cstr(cstr, clen, &chunk,
973+
name);
974+
orig->data -= offset;
975+
orig->len += offset;
969976
if (equal)
970977
break;
971978
}
@@ -997,6 +1004,4 @@ tfw_http_search_cookie(const char *cstr, unsigned long clen,
9971004
}
9981005
*pos = tfw_str_collect_cmp(chunk, end, val, ";");
9991006
return 1;
1000-
1001-
#undef TFW_STR_EQ_CSTR
10021007
}

0 commit comments

Comments
 (0)