aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-09-25 09:46:47 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-09-25 09:46:47 +0100
commit0295d3ba5d02bf65370db6bdd197bdd8f50a0f91 (patch)
tree1abcfa4bec6512192f4882a2bf7263366335c60a
parente4dbb877a320ad27592fb3cbfec0f45085c01012 (diff)
downloadrspamd-0295d3ba5d02bf65370db6bdd197bdd8f50a0f91.tar.gz
rspamd-0295d3ba5d02bf65370db6bdd197bdd8f50a0f91.zip
[Fix] Fix out-of-bound read in qp decode
-rw-r--r--src/libutil/str_util.c30
-rw-r--r--test/lua/unit/quoted_printable.lua19
2 files changed, 45 insertions, 4 deletions
diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c
index 91199aec1..f5cd8be1a 100644
--- a/src/libutil/str_util.c
+++ b/src/libutil/str_util.c
@@ -2088,6 +2088,10 @@ rspamd_decode_qp_buf (const gchar *in, gsize inlen,
if (end - o > 0) {
*o++ = *p;
}
+ else {
+ /* Buffer overflow */
+ return (-1);
+ }
break;
}
@@ -2149,9 +2153,29 @@ decode:
processed = pos - o;
remain -= processed;
p += processed;
- o = pos - 1;
- /* Skip comparison, as we know that we have found match */
- goto decode;
+
+ if (remain > 0) {
+ o = pos - 1;
+ /*
+ * Skip comparison and jump inside decode branch,
+ * as we know that we have found match
+ */
+ goto decode;
+ }
+ else {
+ /* Last '=' character, bugon */
+ o = pos;
+
+ if (end - o > 0) {
+ *o = '=';
+ }
+ else {
+ /* Buffer overflow */
+ return (-1);
+ }
+
+ break;
+ }
}
}
else {
diff --git a/test/lua/unit/quoted_printable.lua b/test/lua/unit/quoted_printable.lua
index 50d357ea0..cf667f8d4 100644
--- a/test/lua/unit/quoted_printable.lua
+++ b/test/lua/unit/quoted_printable.lua
@@ -95,6 +95,24 @@ context("Quoted-Printable encoding", function()
assert_rspamd_eq(res)
end)
end
+ -- Decode issues
+ cases = {
+ {
+ 'Mailscape External Mail Flow Outbound Test=',
+ 'Mailscape External Mail Flow Outbound Test=',
+ 'asan found'
+ },
+ }
+
+ for _,c in ipairs(cases) do
+ test("QP decoding test case: " .. c[3], function()
+ local res = {
+ expect = c[2],
+ actual = tostring(rspamd_util.decode_qp(c[1]))
+ }
+ assert_rspamd_eq(res)
+ end)
+ end
-- Fuzz testing
local charset = {}
@@ -109,7 +127,6 @@ context("Quoted-Printable encoding", function()
end
end
-
for _,l in ipairs({10, 100, 1000, 10000}) do
test("QP fuzz test max length " .. tostring(l), function()
for _=1,100 do