diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-09-25 09:46:47 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-09-25 09:46:47 +0100 |
commit | 0295d3ba5d02bf65370db6bdd197bdd8f50a0f91 (patch) | |
tree | 1abcfa4bec6512192f4882a2bf7263366335c60a | |
parent | e4dbb877a320ad27592fb3cbfec0f45085c01012 (diff) | |
download | rspamd-0295d3ba5d02bf65370db6bdd197bdd8f50a0f91.tar.gz rspamd-0295d3ba5d02bf65370db6bdd197bdd8f50a0f91.zip |
[Fix] Fix out-of-bound read in qp decode
-rw-r--r-- | src/libutil/str_util.c | 30 | ||||
-rw-r--r-- | test/lua/unit/quoted_printable.lua | 19 |
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 |