commit 0295d3b: [Fix] Fix out-of-bound read in qp decode

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Sep 25 08:49:05 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-09-25 09:46:47 +0100
URL: https://github.com/rspamd/rspamd/commit/0295d3ba5d02bf65370db6bdd197bdd8f50a0f91 (HEAD -> master)

[Fix] Fix out-of-bound read in qp decode

---
 src/libutil/str_util.c             | 30 +++++++++++++++++++++++++++---
 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


More information about the Commits mailing list