CVE-2022-0729: Use of Out-of-range Pointer Offset (CWE-823)
value: Use of Out-of-range Pointer Offset in GitHub repository vim/vim prior to 8.2.4440.
CWE description: The product performs pointer arithmetic on a valid pointer, but it uses an offset that can point outside of the intended range of valid memory locations for the resulting pointer.
CVSS v3 base score: 8.8
Published: 2022-02-23T14:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/regexp_bt.c, src/testdir/test_regexp_utf8.vim, src/version.c
Commit date: 2022-02-22 13:37:31 +0000
Commit message: patch 8.2.4440: crash with specific regexp pattern and string

Problem:    Crash with specific regexp pattern and string.
Solution:   Stop at the start of the string.

Diff: diff --git a/src/regexp_bt.c b/src/regexp_bt.c
index 5f5e58f834fc..4082f59d35cc 100644
--- a/src/regexp_bt.c
+++ b/src/regexp_bt.c
@@ -4613,10 +4613,15 @@ regmatch(
 			    if (--rst->count < rst->minval)
 				break;
 			    if (rex.input == rex.line)
 			    {
 				// backup to last char of previous line
+				if (rex.lnum == 0)
+				{
+				    status = RA_NOMATCH;
+				    break;
+				}
 				--rex.lnum;
 				rex.line = reg_getline(rex.lnum);
 				// Just in case regrepeat() didn't count
 				// right.
 				if (rex.line == NULL)
diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim
index 674eee571d36..9f5b28816029 100644
--- a/src/testdir/test_regexp_utf8.vim
+++ b/src/testdir/test_regexp_utf8.vim
@@ -506,11 +506,10 @@ func Test_match_start_of_line_combining()
 endfunc
 
 " Check that [[:upper:]] matches for automatic engine
 func Test_match_char_class_upper()
   new
-  let _engine=&regexpengine
 
   " Test 1: [[:upper:]]\{2,\}
   set regexpengine=0
   call setline(1, ['05. ПЕСНЯ О ГЕРОЯХ муз. А. Давиденко, М. Коваля и Б. Шехтера ...', '05. PJESNJA O GJEROJAKH mus. A. Davidjenko, M. Kovalja i B. Shjekhtjera ...'])
   call cursor(1,1)
@@ -547,11 +546,11 @@ func Test_match_char_class_upper()
   set regexpengine=2
   exe search_cmd
   call assert_equal(4, searchcount().total, 'TEST 3 lower')
 
   " clean up
-  let &regexpengine=_engine
+  set regexpengine=0
   bwipe!
 endfunc
 
 func Test_match_invalid_byte()
   call writefile(0z630a.765d30aa0a.2e0a.790a.4030, 'Xinvalid')
@@ -559,6 +558,15 @@ func Test_match_invalid_byte()
   source Xinvalid
   bwipe!
   call delete('Xinvalid')
 endfunc
 
+func Test_match_too_complicated()
+  set regexpengine=1
+  exe "vsplit \xeb\xdb\x99"
+  silent! buf \&\zs*\zs*0
+  bwipe!
+  set regexpengine=0
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 23f45b5c17c0..809b03f3e518 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4440,
 /**/
     4439,
 /**/
     4438,
 /**/

Vulnerable code:   let _engine=&regexpengine
  let &regexpengine=_engine
Fixed code: 				if (rex.lnum == 0)
				{
				    status = RA_NOMATCH;
				    break;
				}
  set regexpengine=0
func Test_match_too_complicated()
  set regexpengine=1
  exe "vsplit \xeb\xdb\x99"
  silent! buf \&\zs*\zs*0
  bwipe!
  set regexpengine=0
endfunc


/**/
    4440,