diff --git a/SOURCES/0001-patch-8.2.4120-block-insert-goes-over-the-end-of-the.patch b/SOURCES/0001-patch-8.2.4120-block-insert-goes-over-the-end-of-the.patch
new file mode 100644
index 0000000..31d30c1
--- /dev/null
+++ b/SOURCES/0001-patch-8.2.4120-block-insert-goes-over-the-end-of-the.patch
@@ -0,0 +1,95 @@
+diff -up vim80/src/ops.c.cve0261 vim80/src/ops.c
+--- vim80/src/ops.c.cve0261	2022-01-26 14:30:27.475308323 +0100
++++ vim80/src/ops.c	2022-01-26 14:34:16.650933713 +0100
+@@ -636,23 +636,30 @@ block_insert(
+ 	    if (b_insert)
+ 	    {
+ 		off = (*mb_head_off)(oldp, oldp + offset + spaces);
++		spaces -= off;
++		count -= off;
+ 	    }
+ 	    else
+ 	    {
+-		off = (*mb_off_next)(oldp, oldp + offset);
+-		offset += off;
++		// spaces fill the gap, the character that's at the edge moves
++		// right
++		off = (*mb_head_off)(oldp, oldp + offset);
++		offset -= off;
+ 	    }
+ 	    spaces -= off;
+ 	    count -= off;
+ 	}
+ #endif
+ 
+-	newp = alloc_check((unsigned)(STRLEN(oldp)) + s_len + count + 1);
++	// Make sure the allocated size matches what is actually copied below.
++	newp = alloc(STRLEN(oldp) + spaces + s_len
++		    + (spaces > 0 && !bdp->is_short ? p_ts - spaces : 0)
++								  + count + 1);
+ 	if (newp == NULL)
+ 	    continue;
+ 
+ 	/* copy up to shifted part */
+-	mch_memmove(newp, oldp, (size_t)(offset));
++	mch_memmove(newp, oldp, (size_t)offset);
+ 	oldp += offset;
+ 
+ 	/* insert pre-padding */
+@@ -662,14 +669,21 @@ block_insert(
+ 	mch_memmove(newp + offset + spaces, s, (size_t)s_len);
+ 	offset += s_len;
+ 
+-	if (spaces && !bdp->is_short)
++	if (spaces > 0 && !bdp->is_short)
+ 	{
+-	    /* insert post-padding */
+-	    vim_memset(newp + offset + spaces, ' ', (size_t)(p_ts - spaces));
+-	    /* We're splitting a TAB, don't copy it. */
+-	    oldp++;
+-	    /* We allowed for that TAB, remember this now */
+-	    count++;
++	    if (*oldp == TAB)
++	    {
++		// insert post-padding
++		vim_memset(newp + offset + spaces, ' ',
++						    (size_t)(p_ts - spaces));
++		// we're splitting a TAB, don't copy it
++		oldp++;
++		// We allowed for that TAB, remember this now
++		count++;
++	    }
++	    else
++		// Not a TAB, no extra spaces
++		count = spaces;
+ 	}
+ 
+ 	if (spaces > 0)
+@@ -2738,9 +2752,9 @@ op_insert(oparg_T *oap, long count1)
+ 		oap->start_vcol = t;
+ 	    }
+ 	    else if (oap->op_type == OP_APPEND
+-		      && oap->end.col
++		      && oap->start.col
+ #ifdef FEAT_VIRTUALEDIT
+-			    + oap->end.coladd
++			    + oap->start.coladd
+ #endif
+ 			>= curbuf->b_op_start_orig.col
+ #ifdef FEAT_VIRTUALEDIT
+diff -up vim80/src/testdir/test_visual.vim.cve0261 vim80/src/testdir/test_visual.vim
+--- vim80/src/testdir/test_visual.vim.cve0261	2022-01-26 14:30:27.476308325 +0100
++++ vim80/src/testdir/test_visual.vim	2022-01-26 14:36:03.482225225 +0100
+@@ -254,3 +254,12 @@ func Test_virtual_replace2()
+   %d_
+   set bs&vim
+ endfunc
++
++func Test_visual_block_append_invalid_char()
++  " this was going over the end of the line
++  new
++  call setline(1, ['	   let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
++  exe "normal 0\<C-V>jjA-\<Esc>"
++  call assert_equal(['	-   let xxx', 'xxxxx   -ˆ', 'xxxxxxxx-xxx'], getline(1, 3))
++  bwipe!
++endfunc
diff --git a/SOURCES/0001-patch-8.2.4151-reading-beyond-the-end-of-a-line.patch b/SOURCES/0001-patch-8.2.4151-reading-beyond-the-end-of-a-line.patch
new file mode 100644
index 0000000..8e92918
--- /dev/null
+++ b/SOURCES/0001-patch-8.2.4151-reading-beyond-the-end-of-a-line.patch
@@ -0,0 +1,46 @@
+diff --git a/src/ops.c b/src/ops.c
+index e9cfb1d..e35b033 100644
+--- a/src/ops.c
++++ b/src/ops.c
+@@ -629,26 +629,9 @@ block_insert(
+ 
+ #ifdef FEAT_MBYTE
+ 	if (has_mbyte && spaces > 0)
+-	{
+-	    int off;
++	    // avoid copying part of a multi-byte character
++	    offset -= (*mb_head_off)(oldp, oldp + offset);
+ 
+-	    /* Avoid starting halfway a multi-byte character. */
+-	    if (b_insert)
+-	    {
+-		off = (*mb_head_off)(oldp, oldp + offset + spaces);
+-		spaces -= off;
+-		count -= off;
+-	    }
+-	    else
+-	    {
+-		// spaces fill the gap, the character that's at the edge moves
+-		// right
+-		off = (*mb_head_off)(oldp, oldp + offset);
+-		offset -= off;
+-	    }
+-	    spaces -= off;
+-	    count -= off;
+-	}
+ #endif
+ 
+ 	// Make sure the allocated size matches what is actually copied below.
+diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim
+index 24e3db8..1042720 100644
+--- a/src/testdir/test_utf8.vim
++++ b/src/testdir/test_utf8.vim
+@@ -9,7 +9,7 @@ func Test_visual_block_insert()
+   new
+   call setline(1, ["aaa", "あああ", "bbb"])
+   exe ":norm! gg0l\<C-V>jjIx\<Esc>"
+-  call assert_equal(['axaa', 'xあああ', 'bxbb'], getline(1, '$'))
++  call assert_equal(['axaa', ' xあああ', 'bxbb'], getline(1, '$'))
+   bwipeout!
+ endfunc
+ 
diff --git a/SOURCES/0001-patch-8.2.4214-illegal-memory-access-with-large-tabs.patch b/SOURCES/0001-patch-8.2.4214-illegal-memory-access-with-large-tabs.patch
new file mode 100644
index 0000000..98e738c
--- /dev/null
+++ b/SOURCES/0001-patch-8.2.4214-illegal-memory-access-with-large-tabs.patch
@@ -0,0 +1,12 @@
+diff -up vim80/src/ex_getln.c.cve0359 vim80/src/ex_getln.c
+--- vim80/src/ex_getln.c.cve0359	2022-01-27 16:55:41.386213891 +0100
++++ vim80/src/ex_getln.c	2022-01-27 17:00:20.330960544 +0100
+@@ -300,7 +300,7 @@ getcmdline(
+     ccline.cmdindent = (firstc > 0 ? indent : 0);
+ 
+     /* alloc initial ccline.cmdbuff */
+-    alloc_cmdbuff(exmode_active ? 250 : indent + 1);
++    alloc_cmdbuff(indent + 50);
+     if (ccline.cmdbuff == NULL)
+ 	return NULL;			    /* out of memory */
+     ccline.cmdlen = ccline.cmdpos = 0;
diff --git a/SPECS/vim.spec b/SPECS/vim.spec
index 0c0402a..ad1194c 100644
--- a/SPECS/vim.spec
+++ b/SPECS/vim.spec
@@ -24,7 +24,7 @@ Summary: The VIM editor
 URL:     http://www.vim.org/
 Name: vim
 Version: %{baseversion}.%{patchlevel}
-Release: 16%{?dist}.4
+Release: 16%{?dist}.7
 License: Vim and MIT
 Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}-%{patchlevel}.tar.bz2
 Source1: vim.sh
@@ -88,6 +88,12 @@ Patch3026: 0001-patch-8.2.3669-buffer-overflow-with-long-help-argume.patch
 Patch3027: 0001-patch-8.2.3950-going-beyond-the-end-of-the-line-with.patch
 # CVE-2021-4192 vim: vulnerable to Use After Free
 Patch3028: 0001-patch-8.2.3949-using-freed-memory-with-V.patch
+# CVE-2022-0261 vim: Heap-based Buffer Overflow in block_insert() in src/ops.c
+Patch3029: 0001-patch-8.2.4120-block-insert-goes-over-the-end-of-the.patch
+# CVE-2022-0318 vim: heap-based buffer overflow in utf_head_off() in mbyte.c
+Patch3030: 0001-patch-8.2.4151-reading-beyond-the-end-of-a-line.patch
+# CVE-2022-0359 vim: heap-based buffer overflow in init_ccline() in ex_getln.c
+Patch3031: 0001-patch-8.2.4214-illegal-memory-access-with-large-tabs.patch
 
 # gcc is no longer in buildroot by default
 BuildRequires: gcc
@@ -293,6 +299,9 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk
 %patch3026 -p1 -b .cve4019
 %patch3027 -p1 -b .cve4193
 %patch3028 -p1 -b .cve4192
+%patch3029 -p1 -b .cve0261
+%patch3030 -p1 -b .cve0318
+%patch3031 -p1 -b .cve0359
 
 %build
 %if 0%{?rhel} > 7
@@ -811,6 +820,16 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags
 %{_datadir}/icons/locolor/*/apps/*
 
 %changelog
+* Thu Jan 27 2022 Zdenek Dohnal <zdohnal@redhat.com> - 2:8.0.1763-16.7
+- CVE-2022-0359 vim: heap-based buffer overflow in init_ccline() in ex_getln.c
+
+* Thu Jan 27 2022 Zdenek Dohnal <zdohnal@redhat.com> - 2:8.0.1763-16.6
+- fix test suite after fix for CVE-2022-0318
+
+* Wed Jan 26 2022 Zdenek Dohnal <zdohnal@redhat.com> - 2:8.0.1763-16.5
+- CVE-2022-0261 vim: Heap-based Buffer Overflow in block_insert() in src/ops.c
+- CVE-2022-0318 vim: heap-based buffer overflow in utf_head_off() in mbyte.c
+
 * Wed Jan 12 2022 Zdenek Dohnal <zdohnal@redhat.com> - 2:8.0.1763-16.4
 - CVE-2021-4193 vim: vulnerable to Out-of-bounds Read
 - CVE-2021-4192 vim: vulnerable to Use After Free