diff --git a/SOURCES/gnutls-3.6.14-fix-iovec-memory-leak.patch b/SOURCES/gnutls-3.6.14-fix-iovec-memory-leak.patch
new file mode 100644
index 0000000..15b2c51
--- /dev/null
+++ b/SOURCES/gnutls-3.6.14-fix-iovec-memory-leak.patch
@@ -0,0 +1,152 @@
+From 6fbff7fc8aabeee2254405f254220bbe8c05c67d Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno@gnu.org>
+Date: Fri, 5 Jun 2020 16:26:33 +0200
+Subject: [PATCH] crypto-api: always allocate memory when serializing iovec_t
+
+The AEAD iov interface falls back to serializing the input buffers if
+the low-level cipher doesn't support scatter/gather encryption.
+However, there was a bug in the functions used for the serialization,
+which causes memory leaks under a certain condition (i.e. the number
+of input buffers is 1).
+
+This patch makes the logic of the functions simpler, by removing a
+micro-optimization that tries to minimize the number of calls to
+malloc/free.
+
+The original problem was reported by Marius Steffen in:
+https://bugzilla.samba.org/show_bug.cgi?id=14399
+and the cause was investigated by Alexander Haase in:
+https://gitlab.com/gnutls/gnutls/-/merge_requests/1277
+
+Signed-off-by: Daiki Ueno <ueno@gnu.org>
+---
+ lib/crypto-api.c        | 36 +++++++++++-------------------------
+ tests/aead-cipher-vec.c | 33 ++++++++++++++++++---------------
+ 2 files changed, 29 insertions(+), 40 deletions(-)
+
+diff --git a/lib/crypto-api.c b/lib/crypto-api.c
+index 45be64ed1..8524f5ed4 100644
+--- a/lib/crypto-api.c
++++ b/lib/crypto-api.c
+@@ -891,32 +891,23 @@ gnutls_aead_cipher_encrypt(gnutls_aead_cipher_hd_t handle,
+ struct iov_store_st {
+ 	void *data;
+ 	size_t size;
+-	unsigned allocated;
+ };
+ 
+ static void iov_store_free(struct iov_store_st *s)
+ {
+-	if (s->allocated) {
+-		gnutls_free(s->data);
+-		s->allocated = 0;
+-	}
++	gnutls_free(s->data);
+ }
+ 
+ static int iov_store_grow(struct iov_store_st *s, size_t length)
+ {
+-	if (s->allocated || s->data == NULL) {
+-		s->size += length;
+-		s->data = gnutls_realloc(s->data, s->size);
+-		if (s->data == NULL)
+-			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+-		s->allocated = 1;
+-	} else {
+-		void *data = s->data;
+-		size_t size = s->size + length;
+-		s->data = gnutls_malloc(size);
+-		memcpy(s->data, data, s->size);
+-		s->size += length;
+-	}
++	void *data;
++
++	s->size += length;
++	data = gnutls_realloc(s->data, s->size);
++	if (data == NULL)
++		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
++
++	s->data = data;
+ 	return 0;
+ }
+ 
+@@ -926,11 +917,6 @@ copy_from_iov(struct iov_store_st *dst, const giovec_t *iov, int iovcnt)
+ 	memset(dst, 0, sizeof(*dst));
+ 	if (iovcnt == 0) {
+ 		return 0;
+-	} else if (iovcnt == 1) {
+-		dst->data = iov[0].iov_base;
+-		dst->size = iov[0].iov_len;
+-		/* implies: dst->allocated = 0; */
+-		return 0;
+ 	} else {
+ 		int i;
+ 		uint8_t *p;
+@@ -944,11 +930,11 @@ copy_from_iov(struct iov_store_st *dst, const giovec_t *iov, int iovcnt)
+ 
+ 		p = dst->data;
+ 		for (i=0;i<iovcnt;i++) {
+-			memcpy(p, iov[i].iov_base, iov[i].iov_len);
++			if (iov[i].iov_len > 0)
++				memcpy(p, iov[i].iov_base, iov[i].iov_len);
+ 			p += iov[i].iov_len;
+ 		}
+ 
+-		dst->allocated = 1;
+ 		return 0;
+ 	}
+ }
+diff --git a/tests/aead-cipher-vec.c b/tests/aead-cipher-vec.c
+index fba9010d9..6a30a35f7 100644
+--- a/tests/aead-cipher-vec.c
++++ b/tests/aead-cipher-vec.c
+@@ -49,6 +49,7 @@ static void start(const char *name, int algo)
+ 	giovec_t auth_iov[2];
+ 	uint8_t tag[64];
+ 	size_t tag_size = 0;
++	size_t i;
+ 
+ 	key.data = key16;
+ 	key.size = gnutls_cipher_get_key_size(algo);
+@@ -82,21 +83,23 @@ static void start(const char *name, int algo)
+ 	if (ret < 0)
+ 		fail("gnutls_cipher_init: %s\n", gnutls_strerror(ret));
+ 
+-	ret = gnutls_aead_cipher_encryptv2(ch,
+-					   iv.data, iv.size,
+-					   auth_iov, 2,
+-					   iov, 3,
+-					   tag, &tag_size);
+-	if (ret < 0)
+-		fail("could not encrypt data: %s\n", gnutls_strerror(ret));
+-
+-	ret = gnutls_aead_cipher_decryptv2(ch,
+-					   iv.data, iv.size,
+-					   auth_iov, 2,
+-					   iov, 3,
+-					   tag, tag_size);
+-	if (ret < 0)
+-		fail("could not decrypt data: %s\n", gnutls_strerror(ret));
++	for (i = 0; i < 2; i++) {
++		ret = gnutls_aead_cipher_encryptv2(ch,
++						   iv.data, iv.size,
++						   auth_iov, 2,
++						   iov, i + 1,
++						   tag, &tag_size);
++		if (ret < 0)
++			fail("could not encrypt data: %s\n", gnutls_strerror(ret));
++
++		ret = gnutls_aead_cipher_decryptv2(ch,
++						   iv.data, iv.size,
++						   auth_iov, 2,
++						   iov, i + 1,
++						   tag, tag_size);
++		if (ret < 0)
++			fail("could not decrypt data: %s\n", gnutls_strerror(ret));
++	}
+ 
+ 	gnutls_aead_cipher_deinit(ch);
+ }
+-- 
+2.25.4
+
diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec
index 357a95b..9ec2d80 100644
--- a/SPECS/gnutls.spec
+++ b/SPECS/gnutls.spec
@@ -1,5 +1,5 @@
 Version:	3.6.14
-Release: 5%{?dist}
+Release: 6%{?dist}
 Patch1:	gnutls-3.2.7-rpath.patch
 Patch2:	gnutls-3.6.4-no-now-guile.patch
 Patch3:	gnutls-3.6.13-enable-intel-cet.patch
@@ -8,6 +8,7 @@ Patch5:	gnutls-3.6.14-fips-mode-check.patch
 Patch6:	gnutls-3.6.14-fips-dh-primes.patch
 Patch7:	gnutls-3.6.14-memcmp.patch
 Patch8:	gnutls-3.6.14-fips-dh-check.patch
+Patch9:	gnutls-3.6.14-fix-iovec-memory-leak.patch
 %bcond_without dane
 %if 0%{?rhel}
 %bcond_with guile
@@ -291,6 +292,9 @@ fi
 %endif
 
 %changelog
+* Mon Aug 24 2020 Daiki Ueno <dueno@redhat.com> - 3.6.14-6
+- Fix memory leak when serializing iovec_t (#1844112)
+
 * Sat Jul 18 2020 Daiki Ueno <dueno@redhat.com> - 3.6.14-5
 - Perform validation checks on (EC)DH public keys and share secrets (#1855803)