From patchwork Tue Jun 30 07:18:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 91336 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CECDC43327 for ; Tue, 30 Jun 2026 07:19:20 +0000 (UTC) Received: from mail-dy1-f182.google.com (mail-dy1-f182.google.com [74.125.82.182]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.15491.1782803959447779060 for ; Tue, 30 Jun 2026 00:19:19 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=CwxBBW6Z; spf=pass (domain: mvista.com, ip: 74.125.82.182, mailfrom: hprajapati@mvista.com) Received: by mail-dy1-f182.google.com with SMTP id 5a478bee46e88-30e9eefa268so993704eec.1 for ; Tue, 30 Jun 2026 00:19:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1782803959; x=1783408759; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=3OVNkds5BKU4+10akBKKOnmbpodIr+jGj4sXbIU1Z/g=; b=CwxBBW6ZffWMTW87BehnmWI07C8DJOcFfraiAlnrw4M4FT3Q2GPAf2DDum5O6g1eb3 b5cW0dULCiwRSXiPfy8itpf+5/Man1kgqqlzd/g8hUB06ERpwsITQ+OXi2yVWfpZ9LSe L2F01da14bYqex5oIoE0a5kwTacKCKUJH3gc0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782803959; x=1783408759; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=3OVNkds5BKU4+10akBKKOnmbpodIr+jGj4sXbIU1Z/g=; b=M07F15I1jdpP9/c5ENODbNlQr2hg3o2mlL33esOj4tdudf4P4bQdxkb4Q158L3tvps NYkzn8kPHxsOJMbNp0ExwjETkz/pl5I3XQmWW32hSWF3cJY0OGVYwGyzfyZlPw10Dvxf Pazr+FdF2VbAdvKZGNr1G7B6lu92rMGsmFuMx2iBFWuwHPatJrTjLRm7H9ScXxCBBeGz Byvx9rQc9AmfVht0pHAIrfiVLbzzOtinkT0USKSTptsCUvEUDFwLpmncFnx8tab2h9Ha 3Nm7rjWSZSjeFPSJAX0VUe+bwMAQWCMDfUKAb18h7r/kLGa/GjIPpnb/PqhhWNshEnST Uqow== X-Gm-Message-State: AOJu0YyCZIlzWMpVJgqGW/VCbjU1bKNo9cEsNCZduI/dQN+BqoqCjaXB /I2Ifvern5itwwZo6V99KDx4GtTjG+hVunKe94yxJ/VUwxBeNBxHG5ql+MUa2OgBpLEi55qYhVH 4UbLyM7c= X-Gm-Gg: AfdE7cmZM4c8UpqZHrCqyyQvb0EHodoORzA5DuMkiJ71a4Y5N3jf/1FImYJp7c9txWK Sax+GDkaOdg6eh+Rt70vguFXje+lX2FMqJJwSaKou+P3fxF84t6uuv4gmPrCvXBP2iv4TNv0Fe4 wluyNfYqbItY3ESaBj+jwY6EH71vlNFm+UU3pKxqKZCULObNg/JxJoJxgm1JifVNwZAHCQdmMYv ueMijemLK8hdShRPaAK/9e12VOPu83EISAlk09dJzztrgtolccdB2VFr8BJQk9mkElP2o/zd1Vt ScLqiOjCVbEqtEcewfnhfxO1ucxeYIS/q2Rx35j4OD/DFnKv2fEp3HTQ4gg+82+GJL78RRmz9IJ qYMCfRZwkAU3UcVLCFtI1FJVCgUi6citCyCjOPcFwr18O8jqiOlgIv7uCLXnWvVeQ/bLZIYXIMD JZYcyyIAC3OQ/kujHnb9iaLKWjTQ== X-Received: by 2002:a05:7301:6446:b0:30e:c24e:2f18 with SMTP id 5a478bee46e88-30ee1385b36mr2042015eec.24.1782803958447; Tue, 30 Jun 2026 00:19:18 -0700 (PDT) Received: from MVIN00013.mvista.com ([103.250.136.242]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30ee2fb6514sm4311038eec.7.2026.06.30.00.19.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:19:18 -0700 (PDT) From: Hitendra Prajapati To: openembedded-core@lists.openembedded.org Cc: Hitendra Prajapati Subject: [scarthgap][PATCHv2 1/5] vim: fix for CVE-2026-34982, CVE-2026-34714 & CVE-2026-35177 Date: Tue, 30 Jun 2026 12:48:55 +0530 Message-ID: <20260630071903.155470-1-hprajapati@mvista.com> X-Mailer: git-send-email 2.50.1 MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 30 Jun 2026 07:19:20 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/239853 Pick patch from [1], [2] & [3] also mentioned at NVD report in [4,5 & 6] [1] https://github.com/vim/vim/commit/75661a66a1db1e1f3f1245c615f13a7de44c0587 [2] https://github.com/vim/vim/commit/664701eb7576edb7c7c7d9f2d600815ec1f43459 [3] https://github.com/vim/vim/commit/7088926316d8d4a7572a242d0765e99adfc8b083 [4] https://nvd.nist.gov/vuln/detail/CVE-2026-34982 [5] https://nvd.nist.gov/vuln/detail/CVE-2026-34714 [6] https://nvd.nist.gov/vuln/detail/CVE-2026-35177 More info : CVE-2026-34982 - vim: arbitrary command execution via modeline sandbox bypass. CVE-2026-34714 - vim: Arbitrary code execution via crafted file. CVE-2026-35177 - vim zip.vim plugin: Arbitrary file overwrite via path traversal bypass. Signed-off-by: Hitendra Prajapati --- .../vim/files/CVE-2026-34714.patch | 109 ++++++++++++++++++ .../vim/files/CVE-2026-34982.patch | 105 +++++++++++++++++ .../vim/files/CVE-2026-35177.patch | 58 ++++++++++ meta/recipes-support/vim/vim.inc | 3 + 4 files changed, 275 insertions(+) create mode 100644 meta/recipes-support/vim/files/CVE-2026-34714.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-34982.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-35177.patch diff --git a/meta/recipes-support/vim/files/CVE-2026-34714.patch b/meta/recipes-support/vim/files/CVE-2026-34714.patch new file mode 100644 index 0000000000..fef167e535 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-34714.patch @@ -0,0 +1,109 @@ +From 664701eb7576edb7c7c7d9f2d600815ec1f43459 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Mon, 30 Mar 2026 08:20:43 +0000 +Subject: [PATCH] patch 9.2.0272: [security]: 'tabpanel' can be set in a + modeline + +Problem: 'tabpanel' can be set in a modeline +Solution: Set the P_MLE flag for the 'tabpanel' option, disable + autocmd_add()/autocomd_delete() functions in restricted/secure + mode. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-2gmj-rpqf-pxvh + +Signed-off-by: Christian Brabandt + +CVE: CVE-2026-34714 +Upstream-Status: Backport [https://github.com/vim/vim/commit/664701eb7576edb7c7c7d9f2d600815ec1f43459] +Signed-off-by: Hitendra Prajapati +--- + src/autocmd.c | 3 +++ + src/optiondefs.h | 2 +- + src/testdir/test_autocmd.vim | 5 +++++ + src/testdir/test_tabpanel.vim | 16 ++++++++++++++++ + src/version.c | 2 ++ + 5 files changed, 27 insertions(+), 1 deletion(-) + +diff --git a/src/autocmd.c b/src/autocmd.c +index 94f9c1fba4..8a6b363aad 100644 +--- a/src/autocmd.c ++++ b/src/autocmd.c +@@ -3069,6 +3069,9 @@ autocmd_add_or_delete(typval_T *argvars, typval_T *rettv, int delete) + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_FALSE; + ++ if (check_restricted() || check_secure()) ++ return; ++ + if (check_for_list_arg(argvars, 0) == FAIL) + return; + +diff --git a/src/optiondefs.h b/src/optiondefs.h +index 62d142e637..bd02d04f47 100644 +--- a/src/optiondefs.h ++++ b/src/optiondefs.h +@@ -2570,7 +2570,7 @@ static struct vimoption options[] = + (char_u *)&p_tpm, PV_NONE, NULL, NULL, + {(char_u *)10L, (char_u *)0L} SCTX_INIT}, + #if defined(FEAT_TABPANEL) +- {"tabpanel", "tpl", P_STRING|P_VI_DEF|P_RALL, ++ {"tabpanel", "tpl", P_STRING|P_VI_DEF|P_RALL|P_MLE, + (char_u *)&p_tpl, PV_NONE, NULL, NULL, + {(char_u *)"", (char_u *)0L} SCTX_INIT}, + {"tabpanelopt","tplo", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_COLON +diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim +index 43605f7e11..1fea13b00a 100644 +--- a/src/testdir/test_autocmd.vim ++++ b/src/testdir/test_autocmd.vim +@@ -5501,4 +5501,9 @@ func Test_VimResized_and_window_width_not_equalized() + call StopVimInTerminal(buf) + endfunc + ++func Test_autocmd_add_secure() ++ call assert_fails('sandbox call autocmd_add([{"event": "BufRead", "cmd": "let x = 1"}])', 'E48:') ++ call assert_fails('sandbox call autocmd_delete([{"event": "BufRead"}])', 'E48:') ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/testdir/test_tabpanel.vim b/src/testdir/test_tabpanel.vim +index ecc12b59be..b0d4202dc4 100644 +--- a/src/testdir/test_tabpanel.vim ++++ b/src/testdir/test_tabpanel.vim +@@ -770,4 +770,20 @@ function Test_tabpanel_with_cmdline_pum() + + call StopVimInTerminal(buf) + endfunc ++ ++func Test_tabpanel_no_modeline() ++ let _tpl = &tabpanel ++ let _mls = &modelineexpr ++ ++ set nomodelineexpr ++ setlocal modeline ++ new ++ call writefile(['/* vim: set tabpanel=test: */'], 'Xtabpanel.txt', 'D') ++ call assert_fails(':e Xtabpanel.txt', 'E992:') ++ ++ let &tabpanel = _tpl ++ let &modelineexpr = _mls ++ bw! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/version.c b/src/version.c +index 4f47ec2688..309ddf7f7c 100644 +--- a/src/version.c ++++ b/src/version.c +@@ -724,6 +724,8 @@ static char *(features[]) = + + static int included_patches[] = + { /* Add new patch number below this line */ ++/**/ ++ 1687, + /**/ + 1686, + /**/ +-- +2.50.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-34982.patch b/meta/recipes-support/vim/files/CVE-2026-34982.patch new file mode 100644 index 0000000000..e896f3b44d --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-34982.patch @@ -0,0 +1,105 @@ +From 75661a66a1db1e1f3f1245c615f13a7de44c0587 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 31 Mar 2026 18:29:00 +0000 +Subject: [PATCH] patch 9.2.0276: [security]: modeline security bypass + +Problem: [security]: modeline security bypass +Solution: disallow mapset() from secure mode, set the P_MLE flag for the + 'complete', 'guitabtooltip' and 'printheader' options. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-8h6p-m6gr-mpw9 + +Signed-off-by: Christian Brabandt + +CVE: CVE-2026-34982 +Upstream-Status: Backport [https://github.com/vim/vim/commit/75661a66a1db1e1f3f1245c615f13a7de44c0587] +Signed-off-by: Hitendra Prajapati +--- + src/map.c | 3 +++ + src/optiondefs.h | 6 +++--- + src/testdir/test_modeline.vim | 25 +++++++++++++++++++++++++ + 3 files changed, 31 insertions(+), 3 deletions(-) + +diff --git a/src/map.c b/src/map.c +index fbecf4aced..7677243625 100644 +--- a/src/map.c ++++ b/src/map.c +@@ -2746,6 +2746,9 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED) + int dict_only; + mapblock_T *mp_result[2] = {NULL, NULL}; + ++ if (check_secure()) ++ return; ++ + // If first arg is a dict, then that's the only arg permitted. + dict_only = argvars[0].v_type == VAR_DICT; + if (in_vim9script() +diff --git a/src/optiondefs.h b/src/optiondefs.h +index 77155a63e8..62d142e637 100644 +--- a/src/optiondefs.h ++++ b/src/optiondefs.h +@@ -683,7 +683,7 @@ static struct vimoption options[] = + {"compatible", "cp", P_BOOL|P_RALL, + (char_u *)&p_cp, PV_NONE, did_set_compatible, NULL, + {(char_u *)TRUE, (char_u *)FALSE} SCTX_INIT}, +- {"complete", "cpt", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, ++ {"complete", "cpt", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP|P_MLE, + (char_u *)&p_cpt, PV_CPT, did_set_complete, expand_set_complete, + {(char_u *)".,w,b,u,t,i", (char_u *)0L} + SCTX_INIT}, +@@ -1326,7 +1326,7 @@ static struct vimoption options[] = + {(char_u *)NULL, (char_u *)0L} + #endif + SCTX_INIT}, +- {"guitabtooltip", "gtt", P_STRING|P_VI_DEF|P_RWIN, ++ {"guitabtooltip", "gtt", P_STRING|P_VI_DEF|P_RWIN|P_MLE, + #if defined(FEAT_GUI_TABLINE) + (char_u *)&p_gtt, PV_NONE, NULL, NULL, + {(char_u *)"", (char_u *)0L} +@@ -2044,7 +2044,7 @@ static struct vimoption options[] = + {(char_u *)NULL, (char_u *)0L} + #endif + SCTX_INIT}, +- {"printheader", "pheader", P_STRING|P_VI_DEF|P_GETTEXT, ++ {"printheader", "pheader", P_STRING|P_VI_DEF|P_GETTEXT|P_MLE, + #ifdef FEAT_PRINTER + (char_u *)&p_header, PV_NONE, NULL, NULL, + // untranslated to avoid problems when 'encoding' +diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim +index 1f8686328a..c00032ba72 100644 +--- a/src/testdir/test_modeline.vim ++++ b/src/testdir/test_modeline.vim +@@ -361,4 +361,29 @@ func Test_modeline_disable() + call assert_equal(2, &sw) + endfunc + ++func Test_modeline_forbidden() ++ let tempfile = tempname() ++ let lines =<< trim END ++ some test text for completion ++ vim: set complete=F{->system('touch_should_not_run')} : ++ END ++ call writefile(lines, tempfile, 'D') ++ call assert_fails($'new {tempfile}', 'E992:') ++ bw! ++ let lines =<< trim END ++ some text ++ vim: set guitabtooltip=%{%mapset()%}: ++ END ++ call writefile(lines, tempfile) ++ call assert_fails($'new {tempfile}', 'E992:') ++ bw! ++ let lines =<< trim END ++ some text ++ vim: set printheader=%{mapset('n',0,{})%)%}: ++ END ++ call writefile(lines, tempfile, 'D') ++ call assert_fails($'new {tempfile}', 'E992:') ++ bw! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.35.7 + diff --git a/meta/recipes-support/vim/files/CVE-2026-35177.patch b/meta/recipes-support/vim/files/CVE-2026-35177.patch new file mode 100644 index 0000000000..be1d5884f7 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-35177.patch @@ -0,0 +1,58 @@ +From 7088926316d8d4a7572a242d0765e99adfc8b083 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Wed, 1 Apr 2026 16:23:49 +0000 +Subject: [PATCH] patch 9.2.0280: [security]: path traversal issue in zip.vim +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Problem: [security]: path traversal issue in zip.vim + (Michał Majchrowicz) +Solution: Detect more such attacks and warn the user. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-jc86-w7vm-8p24 + +CVE: CVE-2026-35177 +Upstream-Status: Backport [https://github.com/vim/vim/commit/7088926316d8d4a7572a242d0765e99adfc8b083] +Signed-off-by: Hitendra Prajapati +--- + runtime/autoload/zip.vim | 8 +++++++- + 1 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim +index c46ec44708..e57fbcfde0 100644 +--- a/runtime/autoload/zip.vim ++++ b/runtime/autoload/zip.vim +@@ -16,6 +16,7 @@ + " 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows + " 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly + " 2025 Jul 12 by Vim Project: drop ../ on write to prevent path traversal attacks ++" 2026 Apr 01 by Vim Project: Detect more path traversal attacks + " License: Vim License (see vim's :help license) + " Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1 + " Permission is hereby granted to use and distribute this code, +@@ -246,6 +247,11 @@ fun! zip#Write(fname) + return + endif + ++ if simplify(a:fname) =~ '\.\.[/\\]' ++ call s:Mess('Error', "***error*** (zip#Write) Path Traversal Attack detected, not writing!") ++ return ++ endif ++ + let curdir= getcwd() + let tmpdir= tempname() + if tmpdir =~ '\.' +@@ -344,7 +350,7 @@ fun! zip#Extract() + if fname =~ '/$' + call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory") + return +- elseif fname =~ '^[.]\?[.]/' ++ elseif fname =~ '^[.]\?[.]/' || simplify(fname) =~ '\.\.[/\\]' + call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!") + return + endif +-- +2.35.7 + diff --git a/meta/recipes-support/vim/vim.inc b/meta/recipes-support/vim/vim.inc index 1396ac4fbc..e9b5df291d 100644 --- a/meta/recipes-support/vim/vim.inc +++ b/meta/recipes-support/vim/vim.inc @@ -22,6 +22,9 @@ SRC_URI = "git://github.com/vim/vim.git;branch=master;protocol=https \ file://CVE-2026-28418.patch \ file://CVE-2026-28419.patch \ file://CVE-2026-39881.patch \ + file://CVE-2026-34982.patch \ + file://CVE-2026-34714.patch \ + file://CVE-2026-35177.patch \ " PV .= ".1683" From patchwork Tue Jun 30 07:18:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 91338 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91FF7C43327 for ; Tue, 30 Jun 2026 07:19:30 +0000 (UTC) Received: from mail-dy1-f174.google.com (mail-dy1-f174.google.com [74.125.82.174]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.15493.1782803961669391089 for ; Tue, 30 Jun 2026 00:19:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=Y0xdgm2O; spf=pass (domain: mvista.com, ip: 74.125.82.174, mailfrom: hprajapati@mvista.com) Received: by mail-dy1-f174.google.com with SMTP id 5a478bee46e88-30bf132969bso6044751eec.0 for ; Tue, 30 Jun 2026 00:19:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1782803961; x=1783408761; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iwJzYBc6OAG8LuNCrKWeSZ9RYdpiJnrutzfrdoXsJ1E=; b=Y0xdgm2OxomqS5O+1N0drWB8PHaNAS5NO07xfgls9YwXwLW2eNhZ8/ciL+/+uvLo0M px8cIvoxfuC49kOHy8BlL1sQi1Y2bvBreEPLdRDu09796Jhi9+gCkGOofYGBukHrw7xK oWVfKKD/5/2jSqenivj5w0R2giddM4Baq7sIk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782803961; x=1783408761; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=iwJzYBc6OAG8LuNCrKWeSZ9RYdpiJnrutzfrdoXsJ1E=; b=A1td4jBTyq7KsnLnEr8ywHMmcJ5y8FOVSPVPUOddOux71+g3kUMRmyeX3ElZ1tAUps +jkG8Vwnx93wXrLX5lN20eIKmovD6SM8MoxopLv4jP/yt5mZ6irl9sBqLnFPu8pWJN8w ci6xMvEXtVrvYiyGpMWhgqgplq5+G/h9Jj1wNCXckp1Uq2WNquNeqdRA9/7sHPKX9w/R mcCneazx89Ovc/7tiYfZQgwk2rAMY5q285WdJba47dA1J+kbo2H24nxm2f2bmP/oA3qE DUEscDtAB5SwT/GBn3J3oRuJlvWXzaaJVwv7yRpcLbLL+qlcBVf4J5FvKaJIY57aQSai UP3g== X-Gm-Message-State: AOJu0YwMZ7Y4iflYVtUDSPbvckhVztFVM9YBY4jCEs8F64hEcgDxMpaP O3nH12HWcI2y7qqwYgcRK6qREBRI8FJKcBH1iKKv39Q5LwoHGyyfvJomVggdhsatVDVIx6Il5tP 2QIyLq8M= X-Gm-Gg: AfdE7cmxQAqTLw9L55HiMCkbkgj9x3M73O3ofuqHgVTqb8bA1JWdDWVNBVoOmqNbDf0 dObg8gtlZr1r+TltOFOpiBq1WKbZB3DvXTozquL8cncVxLVNF6AMQixi9djhDxYgN1owVssroFa DZk1Vg3jHvQoefDOo2dKQH7AlgOf29OHXWj7VMuGWJBhZ2r/Nd3vWBV98DrV3hnqYhSNUYzhjHZ 6f20Gs5EW6nXaheQ0b2pdw3bt9mi9bivR4TB9xDo69D2BWD9pxu3OEH+99SPFpcJO1+gi3IRsBT fYum44Wy7ZMAKFoLk65TrGlRhsRlA3WVD/e57NY9Az7fHFF6Z4wKL+FyvBJQbsI4QCRf776KJme SfjcFdgCzElV6oRQIOCEE7MeTLLK2gh7NVpFJ2+nT2099FC/8fmmfcrGJ0NTpsqagoQoJ+ScCut 7UwwWRHgsjEOsODf/u5q2WNrsQKg== X-Received: by 2002:a05:7300:a994:b0:30c:7b76:9047 with SMTP id 5a478bee46e88-30ee13435bcmr1726288eec.17.1782803960792; Tue, 30 Jun 2026 00:19:20 -0700 (PDT) Received: from MVIN00013.mvista.com ([103.250.136.242]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30ee2fb6514sm4311038eec.7.2026.06.30.00.19.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:19:20 -0700 (PDT) From: Hitendra Prajapati To: openembedded-core@lists.openembedded.org Cc: Hitendra Prajapati Subject: [scarthgap][PATCHv2 2/5] vim: fix for CVE-2026-28421, CVE-2026-41411 & CVE-2026-44656 Date: Tue, 30 Jun 2026 12:48:56 +0530 Message-ID: <20260630071903.155470-2-hprajapati@mvista.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260630071903.155470-1-hprajapati@mvista.com> References: <20260630071903.155470-1-hprajapati@mvista.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 30 Jun 2026 07:19:30 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/239854 Pick patch from [1], [2] & [3] also mentioned at NVD report in [4,5 & 6] [1] https://github.com/vim/vim/commit/65c1a143c331c886dc28888dd632708f953b4eb3 [2] https://github.com/vim/vim/commit/c78194e41d5a0b05b0ddf383b6679b1503f977fb [3] https://github.com/vim/vim/commit/190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0 [4] https://nvd.nist.gov/vuln/detail/CVE-2026-28421 [5] https://nvd.nist.gov/vuln/detail/CVE-2026-41411 [6] https://nvd.nist.gov/vuln/detail/CVE-2026-44656 More info : CVE-2026-28421 - Validate block tree indices and readfile() line bounds. CVE-2026-41411 - Disallow backticks before attempting to expand filenames. CVE-2026-44656 - Prevent shell execution from 'path' backticks via modelines. Signed-off-by: Hitendra Prajapati --- .../vim/files/CVE-2026-28421.patch | 148 ++++++++++++++++++ .../vim/files/CVE-2026-41411.patch | 75 +++++++++ .../vim/files/CVE-2026-44656.patch | 130 +++++++++++++++ meta/recipes-support/vim/vim.inc | 3 + 4 files changed, 356 insertions(+) create mode 100644 meta/recipes-support/vim/files/CVE-2026-28421.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-41411.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-44656.patch diff --git a/meta/recipes-support/vim/files/CVE-2026-28421.patch b/meta/recipes-support/vim/files/CVE-2026-28421.patch new file mode 100644 index 0000000000..cd3dd1d13f --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-28421.patch @@ -0,0 +1,148 @@ +From 65c1a143c331c886dc28888dd632708f953b4eb3 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Mon, 23 Feb 2026 21:42:39 +0000 +Subject: [PATCH] patch 9.2.0077: [security]: Crash when recovering a corrupted + swap file + +Problem: memline: a crafted swap files with bogus pe_page_count/pe_bnum + values could cause a multi-GB allocation via mf_get(), and + invalid pe_old_lnum/pe_line_count values could cause a SEGV + when passed to readfile() (ehdgks0627, un3xploitable) +Solution: Add bounds checks on pe_page_count and pe_bnum against + mf_blocknr_max before descending into the block tree, and + validate pe_old_lnum >= 1 and pe_line_count > 0 before calling + readfile(). + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-r2gw-2x48-jj5p + +Signed-off-by: Christian Brabandt + +CVE: CVE-2026-28421 +Upstream-Status: Backport [https://github.com/vim/vim/commit/65c1a143c331c886dc28888dd632708f953b4eb3] +Signed-off-by: Hitendra Prajapati +--- + src/memline.c | 29 ++++++++++++++++++++++++++-- + src/po/vim.pot | 5 ++++- + src/testdir/test_recover.vim | 37 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 68 insertions(+), 3 deletions(-) + +diff --git a/src/memline.c b/src/memline.c +index b93eb0a..15ac203 100644 +--- a/src/memline.c ++++ b/src/memline.c +@@ -1597,8 +1597,12 @@ ml_recover(int checkext) + if (!cannot_open) + { + line_count = pp->pb_pointer[idx].pe_line_count; +- if (readfile(curbuf->b_ffname, NULL, lnum, +- pp->pb_pointer[idx].pe_old_lnum - 1, ++ linenr_T pe_old_lnum = pp->pb_pointer[idx].pe_old_lnum; ++ // Validate pe_line_count and pe_old_lnum from the ++ // untrusted swap file before passing to readfile(). ++ if (line_count <= 0 || pe_old_lnum < 1 || ++ readfile(curbuf->b_ffname, NULL, lnum, ++ pe_old_lnum - 1, + line_count, NULL, 0) != OK) + cannot_open = TRUE; + else +@@ -1629,6 +1633,27 @@ ml_recover(int checkext) + bnum = pp->pb_pointer[idx].pe_bnum; + line_count = pp->pb_pointer[idx].pe_line_count; + page_count = pp->pb_pointer[idx].pe_page_count; ++ // Validate pe_bnum and pe_page_count from the untrusted ++ // swap file before passing to mf_get(), which uses ++ // page_count to calculate allocation size. A bogus value ++ // (e.g. 0x40000000) would cause a multi-GB allocation. ++ // pe_page_count must be >= 1 and bnum + page_count must ++ // not exceed the number of pages in the swap file. ++ if (page_count < 1 ++ || bnum + page_count > mfp->mf_blocknr_max + 1) ++ { ++ ++error; ++ ml_append(lnum++, ++ (char_u *)_("???ILLEGAL BLOCK NUMBER"), ++ (colnr_T)0, TRUE); ++ // Skip this entry and pop back up the stack to keep ++ // recovering whatever else we can. ++ idx = ip->ip_index + 1; ++ bnum = ip->ip_bnum; ++ page_count = 1; ++ --buf->b_ml.ml_stack_top; ++ continue; ++ } + idx = 0; + continue; + } +diff --git a/src/po/vim.pot b/src/po/vim.pot +index 9608271..be79cf0 100644 +--- a/src/po/vim.pot ++++ b/src/po/vim.pot +@@ -8,7 +8,7 @@ msgid "" + msgstr "" + "Project-Id-Version: Vim\n" + "Report-Msgid-Bugs-To: vim-dev@vim.org\n" +-"POT-Creation-Date: 2026-04-30 12:40+0200\n" ++"POT-Creation-Date: 2026-02-27 21:04+0000\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language-Team: LANGUAGE \n" +@@ -1960,6 +1960,9 @@ msgstr "" + msgid "???LINES MISSING" + msgstr "" + ++msgid "???ILLEGAL BLOCK NUMBER" ++msgstr "" ++ + msgid "???BLOCK MISSING" + msgstr "" + +diff --git a/src/testdir/test_recover.vim b/src/testdir/test_recover.vim +index db59223..93425f1 100644 +--- a/src/testdir/test_recover.vim ++++ b/src/testdir/test_recover.vim +@@ -471,4 +471,41 @@ func Test_noname_buffer() + call assert_equal(['one', 'two'], getline(1, '$')) + endfunc + ++" Test for recovering a corrupted swap file, those caused a crash ++func Test_recover_corrupted_swap_file1() ++ CheckUnix ++ " only works correctly on 64bit Unix systems: ++ if v:sizeoflong != 8 || !has('unix') ++ throw 'Skipped: Corrupt Swap file sample requires a 64bit Unix build' ++ endif ++ " Test 1: Heap buffer-overflow ++ new ++ let sample = 'samples/recover-crash1.swp' ++ let target = 'Xpoc1.swp' ++ call filecopy(sample, target) ++ try ++ sil recover! Xpoc1 ++ catch /^Vim\%((\S\+)\)\=:E1364:/ ++ endtry ++ let content = getline(1, '$')->join() ++ call assert_match('???ILLEGAL BLOCK NUMBER', content) ++ call delete(target) ++ bw! ++" ++" " Test 2: Segfault ++ new ++ let sample = 'samples/recover-crash2.swp' ++ let target = 'Xpoc2.swp' ++ call filecopy(sample, target) ++ try ++ sil recover! Xpoc2 ++ catch /^Vim\%((\S\+)\)\=:E1364:/ ++ endtry ++ let content = getline(1, '$')->join() ++ call assert_match('???ILLEGAL BLOCK NUMBER', content) ++ call assert_match('???LINES MISSING', content) ++ call delete(target) ++ bw! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-41411.patch b/meta/recipes-support/vim/files/CVE-2026-41411.patch new file mode 100644 index 0000000000..11a34f4087 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-41411.patch @@ -0,0 +1,75 @@ +From c78194e41d5a0b05b0ddf383b6679b1503f977fb Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Wed, 15 Apr 2026 20:17:17 +0000 +Subject: [PATCH] patch 9.2.0357: [security]: command injection via backticks + in tag files + +Problem: [security]: command injection via backticks in tag files + (Srinivas Piskala Ganesh Babu, Andy Ngo) +Solution: Disallow backticks before attempting to expand filenames. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-cwgx-gcj7-6qh8 + +Supported by AI + +Signed-off-by: Christian Brabandt + +CVE: CVE-2026-41411 +Upstream-Status: Backport [https://github.com/vim/vim/commit/c78194e41d5a0b05b0ddf383b6679b1503f977fb] +Signed-off-by: Hitendra Prajapati +--- + src/tag.c | 4 +++- + src/testdir/test_tagjump.vim | 22 ++++++++++++++++++++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/src/tag.c b/src/tag.c +index d3a7399..0e203f0 100644 +--- a/src/tag.c ++++ b/src/tag.c +@@ -4126,8 +4126,10 @@ expand_tag_fname(char_u *fname, char_u *tag_fname, int expand) + + /* + * Expand file name (for environment variables) when needed. ++ * Disallow backticks, they could execute arbitrary shell ++ * commands. This is not needed for tag filenames. + */ +- if (expand && mch_has_wildcard(fname)) ++ if (expand && mch_has_wildcard(fname) && vim_strchr(fname, '`') == NULL) + { + ExpandInit(&xpc); + xpc.xp_context = EXPAND_FILES; +diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim +index 47618d0..a95b8b5 100644 +--- a/src/testdir/test_tagjump.vim ++++ b/src/testdir/test_tagjump.vim +@@ -1670,4 +1670,26 @@ func Test_tag_excmd_with_number_vim9script() + bwipe! + endfunc + ++" Test that backtick expressions in tag filenames are not expanded. ++" This prevents command injection via malicious tags files. ++func Test_tag_backtick_filename_not_expanded() ++ let pwned_file = 'Xtags_pwnd' ++ call assert_false(filereadable(pwned_file)) ++ ++ let tagline = "main\t`touch " .. pwned_file .. "`\t/^int main/;\"\tf" ++ call writefile([tagline], 'Xbt_tags', 'D') ++ call writefile(['int main(int argc, char **argv) {', '}'], 'Xbt_main.c', 'D') ++ ++ set tags=Xbt_tags ++ sp Xbt_main.c ++ ++ " The :tag command should fail to find the file, but must NOT execute ++ " the backtick shell command. ++ call assert_fails('tag main', 'E429:') ++ call assert_false(filereadable(pwned_file)) ++ ++ set tags& ++ bwipe! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-44656.patch b/meta/recipes-support/vim/files/CVE-2026-44656.patch new file mode 100644 index 0000000000..70cd72b098 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-44656.patch @@ -0,0 +1,130 @@ +From 190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Sun, 3 May 2026 16:10:03 +0000 +Subject: [PATCH] patch 9.2.0435: [security]: backticks in 'path' may cause + shell execution on completion + +Problem: [security]: Backticks enclosed shell commands in the 'path' + option value are executed during completion (q1uf3ng). +Solution: Skip path entries containing backticks, add P_SECURE to 'path' + option, so that it cannot be set from a modeline (for symmetry with + the 'cdpath' option) + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-hwg5-3cxw-wvvg + +Supported by AI. + +Signed-off-by: Christian Brabandt + +CVE: CVE-2026-44656 +Upstream-Status: Backport [https://github.com/vim/vim/commit/190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0] +Signed-off-by: Hitendra Prajapati +--- + runtime/doc/options.txt | 5 ++++- + src/findfile.c | 4 ++++ + src/optiondefs.h | 2 +- + src/testdir/test_find_complete.vim | 17 +++++++++++++++++ + src/testdir/test_modeline.vim | 14 ++++++++++++++ + 5 files changed, 40 insertions(+), 2 deletions(-) + +diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt +index 8dba6f4..d06411f 100644 +--- a/runtime/doc/options.txt ++++ b/runtime/doc/options.txt +@@ -1,4 +1,4 @@ +-*options.txt* For Vim version 9.1. Last change: 2025 Aug 23 ++*options.txt* For Vim version 9.2. Last change: 2026 May 03 + + + VIM REFERENCE MANUAL by Bram Moolenaar +@@ -6615,6 +6615,9 @@ A jump table for the options with a short description can be found at |Q_op|. + < Replace the ';' with a ':' or whatever separator is used. Note that + this doesn't work when $INCL contains a comma or white space. + ++ This option cannot be set from a |modeline| or in the |sandbox|, for ++ security reasons. ++ + *'perldll'* + 'perldll' string (default depends on the build) + global +diff --git a/src/findfile.c b/src/findfile.c +index 008338c..f73a66b 100644 +--- a/src/findfile.c ++++ b/src/findfile.c +@@ -2412,6 +2412,10 @@ expand_path_option( + { + buflen = copy_option_part(&path_option, buf, MAXPATHL, " ,"); + ++ // do not expand backticks, could have been set via a modeline ++ if (vim_strchr(buf, '`') != NULL) ++ continue; ++ + if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1]))) + { + size_t plen; +diff --git a/src/optiondefs.h b/src/optiondefs.h +index bd02d04..72d3f36 100644 +--- a/src/optiondefs.h ++++ b/src/optiondefs.h +@@ -1957,7 +1957,7 @@ static struct vimoption options[] = + (char_u *)&p_pm, PV_NONE, + did_set_backupext_or_patchmode, NULL, + {(char_u *)"", (char_u *)0L} SCTX_INIT}, +- {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP, ++ {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE|P_COMMA|P_NODUP, + (char_u *)&p_path, PV_PATH, NULL, NULL, + { + #if defined(AMIGA) || defined(MSWIN) +diff --git a/src/testdir/test_find_complete.vim b/src/testdir/test_find_complete.vim +index 079fb78..8b8b71c 100644 +--- a/src/testdir/test_find_complete.vim ++++ b/src/testdir/test_find_complete.vim +@@ -161,4 +161,21 @@ func Test_find_complete() + set path& + endfunc + ++" Verify that backticks in 'path' are not executed ++func Test_find_completion_backtick_in_path() ++ CheckUnix ++ CheckExecutable id ++ ++ new Xpoc.c ++ setl path+=`id>Xrce_marker` ++ " Triggering completion must not execute the backtick command. ++ call getcompletion('', 'file_in_path') ++ call assert_false(filereadable('Xrce_marker')) ++ call feedkeys(":find \t\n", "xt") ++ call assert_false(filereadable('Xrce_marker')) ++ ++ bwipe! ++ call delete('Xrce_marker') ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim +index c00032b..fc11cc6 100644 +--- a/src/testdir/test_modeline.vim ++++ b/src/testdir/test_modeline.vim +@@ -386,4 +386,18 @@ func Test_modeline_forbidden() + bw! + endfunc + ++" Verify that backticks in 'path' set from a modeline are not executed ++func Test_path_modeline() ++ let lines =<< trim END ++ // vim: set path+=foobar : ++ END ++ call writefile(lines, 'Xpoc.c', 'D') ++ ++ set nomodelinestrict modeline ++ call assert_fails('split Xpoc.c', 'E520:') ++ ++ bwipe! ++ set modelinestrict& modeline& ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/vim.inc b/meta/recipes-support/vim/vim.inc index e9b5df291d..b7cdd61c93 100644 --- a/meta/recipes-support/vim/vim.inc +++ b/meta/recipes-support/vim/vim.inc @@ -25,6 +25,9 @@ SRC_URI = "git://github.com/vim/vim.git;branch=master;protocol=https \ file://CVE-2026-34982.patch \ file://CVE-2026-34714.patch \ file://CVE-2026-35177.patch \ + file://CVE-2026-44656.patch \ + file://CVE-2026-41411.patch \ + file://CVE-2026-28421.patch \ " PV .= ".1683" From patchwork Tue Jun 30 07:18:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 91339 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1577C44501 for ; Tue, 30 Jun 2026 07:19:30 +0000 (UTC) Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.15494.1782803964169842154 for ; Tue, 30 Jun 2026 00:19:24 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=EjpnJdaA; spf=pass (domain: mvista.com, ip: 74.125.82.178, mailfrom: hprajapati@mvista.com) Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-30edfd9cff9so1041321eec.1 for ; Tue, 30 Jun 2026 00:19:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1782803963; x=1783408763; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SJSpfnjEcRRrnYCNDdGYizq+0NhaAD43pRh8bYBS/BQ=; b=EjpnJdaAclwK+oNzzwCDwYog+ugCoAxL8IklA10Cl8NbtQXwKCWy2JxdtYRY2GG/7r OHk3QhdifDwPcEkglSw53QDKXJLDHSGocnwAoysOPLDPDIe79/pMV6X0MIWsYQ2Zuy1l hnTdJC8558ZOtjFjjeg0pdKBSdTXo4VaRNDBs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782803963; x=1783408763; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SJSpfnjEcRRrnYCNDdGYizq+0NhaAD43pRh8bYBS/BQ=; b=mPpi+9txE2NUnVOLpTYU661ol2iTceHzWhnoPTg6nYYvxu17Y518hUIAxatFUMJ3Zh DL+kNjc3AQy+IUOD5ctjg5fRTj9Bp6Cxv4ycukOWWqKDYC+Ea5iU8DGOg/vC/S8tpKI2 MZ6Ffne8HHWeRoHtc/R5xYFPWRwf9w3Rk0R6sdtWkWv+QIjT3NLS3+oENvT4RVgj5WnX /p7NiNFpC9dFIbyj8MLMS47YaJzQNyREs4QmHIP8nXQtmXXIzTdYhpHFMYeErTbPOOtU juD9JotHD/V3SHCzWyp1Neen5GfO5ArddAYLqmdooCPTIdm3GVY0Reced3na+3lI/vl5 0OVA== X-Gm-Message-State: AOJu0Yx1f55HgDOuSj5I7rV+d2+lV+U8Mh9Q+2vy8s0bbg1k+P97b3N4 p0WCqAIutN8ns3vBlJ/9ps8qMQZwsgxlL1h9qFpQ1bD+hQeWkD27aVSUSl8XI2trlH7DXpVfV0w F/uT3ueA= X-Gm-Gg: AfdE7cnfXfGrGdEi7xkCSs6p6lsy3mFxE9HFY+9GBPT8ttacyhkHw1drG5IYD6umlCA PooBvnbcmKEm0tplc77DrLMoz97cHms8FGu0QLWifSw2vMq06qf+bmTvHZbFkZnE4Z4LmLJcLVt 9+lC2lhDKpRZNbA5usF1zNecQRtInatrXidbqgRxC1vP4oNdda1+HM5Qi9Zx0Y3pf7+lQiCZhBZ bnUUWdRQGdRwIPLS/Y/2AGWd5SOPUB1JbQqwSkRTe3HrIvBsQYuI5qPvzeiUBwqIB+BGhM4+1ta E8Vg3nUBtq52eyHtTUHb/M231i1HR+aktfC2ot3UAAjJzxo+6o0D/2yTYjASLHOrF3+xmV76G3d xsCjkpG5TeZ5VkZc/6Y2oBUzsm+FJR9L322ehSDOpPjU712GDc8olkYyxtJmohhII/Z4TJL5BwJ VkcIjNbMbVPyAUyIXP7h4wt1OhQw== X-Received: by 2002:a05:7300:8193:b0:30b:f6cd:fdca with SMTP id 5a478bee46e88-30ee131d85fmr2205975eec.17.1782803963214; Tue, 30 Jun 2026 00:19:23 -0700 (PDT) Received: from MVIN00013.mvista.com ([103.250.136.242]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30ee2fb6514sm4311038eec.7.2026.06.30.00.19.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:19:22 -0700 (PDT) From: Hitendra Prajapati To: openembedded-core@lists.openembedded.org Cc: Hitendra Prajapati Subject: [scarthgap][PATCHv2 3/5] vim: Fix for CVE-2026-28417, CVE-2026-32249, CVE-2026-45130 Date: Tue, 30 Jun 2026 12:48:57 +0530 Message-ID: <20260630071903.155470-3-hprajapati@mvista.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260630071903.155470-1-hprajapati@mvista.com> References: <20260630071903.155470-1-hprajapati@mvista.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 30 Jun 2026 07:19:30 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/239855 Pick patch from [1], [2] & [3] also mentioned at NVD report in [4,5 & 6] [1] https://github.com/vim/vim/commit/79348dbbc09332130f4c86045e1541d68514fcc1 [2] https://github.com/vim/vim/commit/36d6e87542cf823d833e451e09a90ee429899cec [3] https://github.com/vim/vim/commit/92993329178cb1f72d700fff45ca86e1c2d369f8 [4] https://nvd.nist.gov/vuln/detail/CVE-2026-28417 [5] https://nvd.nist.gov/vuln/detail/CVE-2026-32249 [6] https://nvd.nist.gov/vuln/detail/CVE-2026-45130 Signed-off-by: Hitendra Prajapati --- .../vim/files/CVE-2026-28417.patch | 92 ++++++++++++++ .../vim/files/CVE-2026-32249.patch | 117 ++++++++++++++++++ .../vim/files/CVE-2026-45130.patch | 115 +++++++++++++++++ meta/recipes-support/vim/vim.inc | 3 + 4 files changed, 327 insertions(+) create mode 100644 meta/recipes-support/vim/files/CVE-2026-28417.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-32249.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-45130.patch diff --git a/meta/recipes-support/vim/files/CVE-2026-28417.patch b/meta/recipes-support/vim/files/CVE-2026-28417.patch new file mode 100644 index 0000000000..c36bd9c234 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-28417.patch @@ -0,0 +1,92 @@ +From 79348dbbc09332130f4c86045e1541d68514fcc1 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Sun, 22 Feb 2026 21:24:48 +0000 +Subject: [PATCH] patch 9.2.0073: [security]: possible command injection using + netrw + +Problem: [security]: Insufficient validation of hostname and port in + netrw URIs allows command injection via shell metacharacters + (ehdgks0627, un3xploitable). +Solution: Implement stricter RFC1123 hostname and IP validation. + Use shellescape() for the provided hostname and port. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-m3xh-9434-g336 + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/79348dbbc09332130f4c86045e1541d68514fcc1] +CVE: CVE-2026-28417 +Signed-off-by: Hitendra Prajapati +--- + .../pack/dist/opt/netrw/autoload/netrw.vim | 34 +++++++++++++------ + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/runtime/pack/dist/opt/netrw/autoload/netrw.vim b/runtime/pack/dist/opt/netrw/autoload/netrw.vim +index 1c98104..7ebcd92 100644 +--- a/runtime/pack/dist/opt/netrw/autoload/netrw.vim ++++ b/runtime/pack/dist/opt/netrw/autoload/netrw.vim +@@ -5,6 +5,7 @@ + " 2025 Aug 07 by Vim Project (use correct "=~#" for netrw_stylesize option #17901) + " 2025 Aug 07 by Vim Project (netrw#BrowseX() distinguishes remote files #17794) + " 2025 Aug 22 by Vim Project netrw#Explore handle terminal correctly #18069 ++" 2026 Feb 27 by Vim Project Make the hostname validation more strict + " Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 + " Permission is hereby granted to use and distribute this code, + " with or without modifications, provided that this copyright +@@ -2575,13 +2576,26 @@ endfunction + + " s:NetrwValidateHostname: Validate that the hostname is valid {{{2 + " Input: +-" hostname ++" hostname, may include an optional username, e.g. user@hostname ++" allow a alphanumeric hostname or an IPv(4/6) address + " Output: + " true if g:netrw_machine is valid according to RFC1123 #Section 2 + function s:NetrwValidateHostname(hostname) +- " RFC1123#section-2 mandates, a valid hostname starts with letters or digits +- " so reject everyhing else +- return a:hostname =~? '^[a-z0-9]' ++ " Username: ++ let user_pat = '\%([a-zA-Z0-9._-]\+@\)\?' ++ " Hostname: 1-64 chars, alphanumeric/dots/hyphens. ++ " No underscores. No leading/trailing dots/hyphens. ++ let host_pat = '[a-zA-Z0-9]\%([-a-zA-Z0-9.]{,62}[a-zA-Z0-9]\)\?$' ++ ++ " IPv4: 1-3 digits separated by dots ++ let ipv4_pat = '\%(\d\{1,3}\.\)\{3\}\d\{1,3\}$' ++ ++ " IPv6: Hex, colons, and optional brackets ++ let ipv6_pat = '\[\?\%([a-fA-F0-9:]\{2,}\)\+\]\?$' ++ ++ return a:hostname =~? '^'.user_pat.host_pat || ++ \ a:hostname =~? '^'.user_pat.ipv4_pat || ++ \ a:hostname =~? '^'.user_pat.ipv6_pat + endfunction + + " NetUserPass: set username and password for subsequent ftp transfer {{{2 +@@ -8948,15 +8962,15 @@ endfunction + " s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2 + " a correct command for use with a system() call + function s:MakeSshCmd(sshcmd) +- if s:user == "" +- let sshcmd = substitute(a:sshcmd,'\',s:machine,'') +- else +- let sshcmd = substitute(a:sshcmd,'\',s:user."@".s:machine,'') ++ let machine = shellescape(s:machine, 1) ++ if s:user != '' ++ let machine = shellescape(s:user, 1).'@'.machine + endif ++ let sshcmd = substitute(a:sshcmd,'\',machine,'') + if exists("g:netrw_port") && g:netrw_port != "" +- let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'') ++ let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.shellescape(g:netrw_port,1),'') + elseif exists("s:port") && s:port != "" +- let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'') ++ let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.shellescape(s:port,1),'') + else + let sshcmd= substitute(sshcmd,"USEPORT ",'','') + endif +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-32249.patch b/meta/recipes-support/vim/files/CVE-2026-32249.patch new file mode 100644 index 0000000000..18691c3f4c --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-32249.patch @@ -0,0 +1,117 @@ +From 36d6e87542cf823d833e451e09a90ee429899cec Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Wed, 11 Mar 2026 14:16:29 +0100 +Subject: [PATCH] patch 9.2.0137: [security]: crash with composing char in + collection range + +Problem: Using a composing character as the end of a range inside a + collection may corrupt the NFA postfix stack + (Nathan Mills, after v9.1.0011) +Solution: When a character is used as the endpoint of a range, do not emit + its composing characters separately. Range handling only uses + the base codepoint. + +supported by AI + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-9phh-423r-778r + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/36d6e87542cf823d833e451e09a90ee429899cec] +CVE: CVE-2026-32249 +Signed-off-by: Hitendra Prajapati +--- + src/regexp_nfa.c | 17 +++++++++++++++-- + src/testdir/test_regexp_utf8.vim | 19 +++++++++++++++++++ + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c +index 6ad682b..7905ec1 100644 +--- a/src/regexp_nfa.c ++++ b/src/regexp_nfa.c +@@ -1765,6 +1765,7 @@ collection: + if (*endp == ']') + { + int plen; ++ bool range_endpoint; + /* + * Try to reverse engineer character classes. For example, + * recognize that [0-9] stands for \d and [A-Za-z_] for \h, +@@ -1812,6 +1813,7 @@ collection: + while (regparse < endp) + { + int oldstartc = startc; ++ range_endpoint = false; + + startc = -1; + got_coll_char = FALSE; +@@ -1975,6 +1977,7 @@ collection: + if (emit_range) + { + int endc = startc; ++ range_endpoint = true; + + startc = oldstartc; + if (startc > endc) +@@ -2053,7 +2056,14 @@ collection: + } + } + +- if (enc_utf8 && (utf_ptr2len(regparse) != (plen = utfc_ptr2len(regparse)))) ++ // ++ // If this character was consumed as the end of a range, do not emit its ++ // composing characters separately. Range handling only uses the base ++ // codepoint; emitting the composing part again would duplicate the ++ // character in the postfix stream and corrupt the NFA stack. ++ // ++ if (!range_endpoint && enc_utf8 && ++ (utf_ptr2len(regparse) != (plen = utfc_ptr2len(regparse)))) + { + int i = utf_ptr2len(regparse); + +@@ -3187,7 +3197,10 @@ nfa_max_width(nfa_state_T *startstate, int depth) + ++len; + if (state->c != NFA_ANY) + { +- // skip over the characters ++ // Skip over the compiled collection. ++ // malformed NFAs must not crash width estimation. ++ if (state->out1 == NULL || state->out1->out == NULL) ++ return -1; + state = state->out1->out; + continue; + } +diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim +index a4353f1..3b58416 100644 +--- a/src/testdir/test_regexp_utf8.vim ++++ b/src/testdir/test_regexp_utf8.vim +@@ -615,6 +615,25 @@ func Test_search_multibyte_match_ascii() + call assert_equal(['ſſ','ſ'], noic_match3, "No-Ignorecase Collection Regex-engine: " .. &re) + endfor + bw! ++ set ignorecase&vim re&vim ++endfun ++ ++func Test_regex_collection_range_with_composing_crash() ++ " Regression test: composing char in collection range caused NFA crash/E874 ++ new ++ call setline(1, ['00', '0ֻ', '01']) ++ let patterns = [ '0[0-0ֻ]\@", 'E486:') ++ endfor ++ endfor ++ ++ bwipe! + endfunc + + " vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-45130.patch b/meta/recipes-support/vim/files/CVE-2026-45130.patch new file mode 100644 index 0000000000..0a1a93de99 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-45130.patch @@ -0,0 +1,115 @@ +From 92993329178cb1f72d700fff45ca86e1c2d369f8 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Wed, 6 May 2026 20:50:00 +0200 +Subject: [PATCH] patch 9.2.0450: [security]: heap buffer overflow in + spellfile.c read_compound() + +Problem: read_compound() in spellfile.c computes the size of the regex + pattern buffer using signed-int arithmetic on the attacker + controlled SN_COMPOUND sectionlen. With sectionlen=0x40000008 + and UTF-8 encoding active the multiplication wraps to 27 while + the per-byte loop writes up to ~1B bytes, overflowing the heap. + Reachable when loading a crafted .spl file (e.g. via 'set spell' + after a modeline sets 'spelllang'). The cp/ap/crp allocations + have the same int + 1 overflow class (Daniel Cervera) +Solution: Use type size_t as buffer size and reject values larger than + COMPOUND_MAX_LEN (100000). Apply the same size_t treatment to + the cp/ap/crp allocations. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-q4jv-r9gj-6cwv + +Co-Authored-By: Claude Opus 4.7 (1M context) +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/92993329178cb1f72d700fff45ca86e1c2d369f8] +CVE: CVE-2026-45130 +Signed-off-by: Hitendra Prajapati +--- + src/spellfile.c | 20 ++++++++++++++------ + src/testdir/test_spellfile.vim | 4 ++++ + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/src/spellfile.c b/src/spellfile.c +index 0b9536d..768e9fd 100644 +--- a/src/spellfile.c ++++ b/src/spellfile.c +@@ -296,6 +296,9 @@ + #define CF_WORD 0x01 + #define CF_UPPER 0x02 + ++// Max allowed length for COMPOUND section ++#define COMPOUND_MAX_LEN 100000 ++ + /* + * Loop through all the siblings of a node (including the node) + */ +@@ -1225,6 +1228,8 @@ read_compound(FILE *fd, slang_T *slang, int len) + char_u *crp; + int cnt; + garray_T *gap; ++ size_t patsize; ++ size_t flagsize; + + if (todo < 2) + return SP_FORMERROR; // need at least two bytes +@@ -1281,16 +1286,19 @@ read_compound(FILE *fd, slang_T *slang, int len) + // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". + // Inserting backslashes may double the length, "^\(\)$" is 7 bytes. + // Conversion to utf-8 may double the size. +- c = todo * 2 + 7; ++ if ((size_t)todo > COMPOUND_MAX_LEN) ++ return SP_FORMERROR; ++ patsize = (size_t)todo * 2 + 7; + if (enc_utf8) +- c += todo * 2; +- pat = alloc(c); ++ patsize += (size_t)todo * 2; ++ flagsize = (size_t)todo + 1; ++ pat = alloc(patsize); + if (pat == NULL) + return SP_OTHERERROR; + + // We also need a list of all flags that can appear at the start and one + // for all flags. +- cp = alloc(todo + 1); ++ cp = alloc(flagsize); + if (cp == NULL) + { + vim_free(pat); +@@ -1299,7 +1307,7 @@ read_compound(FILE *fd, slang_T *slang, int len) + slang->sl_compstartflags = cp; + *cp = NUL; + +- ap = alloc(todo + 1); ++ ap = alloc(flagsize); + if (ap == NULL) + { + vim_free(pat); +@@ -1311,7 +1319,7 @@ read_compound(FILE *fd, slang_T *slang, int len) + // And a list of all patterns in their original form, for checking whether + // compounding may work in match_compoundrule(). This is freed when we + // encounter a wildcard, the check doesn't work then. +- crp = alloc(todo + 1); ++ crp = alloc(flagsize); + slang->sl_comprules = crp; + + pp = pat; +diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim +index b72974e..d345492 100644 +--- a/src/testdir/test_spellfile.vim ++++ b/src/testdir/test_spellfile.vim +@@ -334,6 +334,10 @@ func Test_spellfile_format_error() + " SN_COMPOUND: incorrect comppatlen + call Spellfile_Test(0z080000000007040101000000020165, 'E758:') + ++ " SN_COMPOUND: oversized sectionlen ++ let v = eval('0z08004000000803010161' .. repeat('61', 50) .. 'FF') ++ call Spellfile_Test(v, 'E759:') ++ + " SN_INFO: missing info + call Spellfile_Test(0z0F0000000005040101, '') + +-- +2.34.1 + diff --git a/meta/recipes-support/vim/vim.inc b/meta/recipes-support/vim/vim.inc index b7cdd61c93..53590befc4 100644 --- a/meta/recipes-support/vim/vim.inc +++ b/meta/recipes-support/vim/vim.inc @@ -28,6 +28,9 @@ SRC_URI = "git://github.com/vim/vim.git;branch=master;protocol=https \ file://CVE-2026-44656.patch \ file://CVE-2026-41411.patch \ file://CVE-2026-28421.patch \ + file://CVE-2026-32249.patch \ + file://CVE-2026-28417.patch \ + file://CVE-2026-45130.patch \ " PV .= ".1683" From patchwork Tue Jun 30 07:18:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 91340 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6CCCC44500 for ; Tue, 30 Jun 2026 07:19:30 +0000 (UTC) Received: from mail-dy1-f172.google.com (mail-dy1-f172.google.com [74.125.82.172]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.15495.1782803966299823442 for ; Tue, 30 Jun 2026 00:19:26 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=ab2ugHlb; spf=pass (domain: mvista.com, ip: 74.125.82.172, mailfrom: hprajapati@mvista.com) Received: by mail-dy1-f172.google.com with SMTP id 5a478bee46e88-30c09f29b64so84257eec.0 for ; Tue, 30 Jun 2026 00:19:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1782803966; x=1783408766; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kEMmiX31aGmIbC3i8Vl6lZI1Fo2WJ9FwNRZfyzQptrc=; b=ab2ugHlbsDgJMPrRzZDgWkT0JzYqPavGkx9zArB+HAEg9N2x61NPF8PlW0JhiRyD/6 jlBnkLbwkLvTPOEK4jyncd2Z1nOxl7GS3Vghgex2TWjLPv8i5wH8FMVjMZPZkOJK1OeR sMWkXXo4BQDnv2lVzqeVQ72aFw4U3ZQiuBPtw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782803966; x=1783408766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=kEMmiX31aGmIbC3i8Vl6lZI1Fo2WJ9FwNRZfyzQptrc=; b=dJYej8HVYzysYJMGqU/A0Ka9HUUxF7KB1zBz4t9EmHztyo1tB7dWP0+OuxwQxdkIwp MA6rAq4iB1zRE0Cz0gN0P6g8gB52P2b9JVTkr6rFIBD2KuKowav4nPAXO8pZpgD77cgM ELqhM+orPpFfVj40vBFqWilp1KKLvhztyUdWoepZCdim5oiUvVXR4teb0Qm+WD6Fw1BS S3Va2G7tUbHjfXjDV+zTN0iAa0TsPRGAF8bwKBPXrRR33RynGlovSVe7QHoIkWlopWIp tpZaXWIVOd7IrrTYXt1UrARECM+WYCSm9rxTHV/WBpLCKQ7aDjr4/JYjVVk4sozBFSUb oLUA== X-Gm-Message-State: AOJu0Yy9OhFcGBtZhl9JFV/57o62cAbyoTJS6dRXplI0oFoH/2lbzKBX wR1E4zSD11BWoqqiim2sYIHwF0zoU6zyqK1vrU8dxrbs8kGXcADV2fjbgOmsrOkCrlc935WQDjb HUCIDOr0= X-Gm-Gg: AfdE7cm/sjRbc1cX0vAvvlWIYt4mbB36ECEPJJq+Bg/PnJYhwPWQecGMuBnYTr5GUAJ lHMTcGCzHkMtA9TwdRztMKHnyUXhHEfrkU7lQiuw6goVtRpm6mSBaNFC8JieGwLmSdi8nvbeTCH +K6kCJ+0Hi6glQfjUUlm+EZGXU7L/09cymnSam/gWrpjQMoMa6roUvoLkoWBPIsnbVG2Wlev2lC j8A8xrEbJQjSOSSdgK6J65gv+SUpFmv2H9bZ8jCYf1ZP5mR0zRhli6tfTXeZMNXnXcXvXYwaO4A xDez8F+62YGDzOqfPk1VVGhQhrjSWzLSj02rGFgt2AC2vIDflt7Ax8X1xTj2IpeaSjmRiRjdEM/ UdltRoyOoYSN1trzu4fKl+Q/8IrYdpC3cW5wG3Hk2gLG4mT/F0yFArxFIGl+wK6WiWxOFwKJWEF cXjlGa+y2gLdBC03XcU30BoI3HXQ== X-Received: by 2002:a05:7300:c88:b0:30c:ab96:7305 with SMTP id 5a478bee46e88-30eea0bbfa2mr557514eec.21.1782803965558; Tue, 30 Jun 2026 00:19:25 -0700 (PDT) Received: from MVIN00013.mvista.com ([103.250.136.242]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30ee2fb6514sm4311038eec.7.2026.06.30.00.19.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:19:25 -0700 (PDT) From: Hitendra Prajapati To: openembedded-core@lists.openembedded.org Cc: Hitendra Prajapati Subject: [scarthgap][PATCHv2 4/5] vim: Security fix for CVE-2026-28420 & CVE-2026-46483 Date: Tue, 30 Jun 2026 12:48:58 +0530 Message-ID: <20260630071903.155470-4-hprajapati@mvista.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260630071903.155470-1-hprajapati@mvista.com> References: <20260630071903.155470-1-hprajapati@mvista.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 30 Jun 2026 07:19:30 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/239856 Pick patch from [1] & [2] also mentioned at NVD report in 3 & 4 [1] https://github.com/vim/vim/commit/bb6de2105b160e729c340631435cd62f3e69bd32 [2] https://github.com/vim/vim/commit/3fb5e58fbc63d86a3e65f1a141b0d67af2aa38a1 [3] https://nvd.nist.gov/vuln/detail/CVE-2026-28420 [4] https://nvd.nist.gov/vuln/detail/CVE-2026-46483 Signed-off-by: Hitendra Prajapati --- .../vim/files/CVE-2026-28420.patch | 162 ++++++++++++++++++ .../vim/files/CVE-2026-46483.patch | 77 +++++++++ meta/recipes-support/vim/vim.inc | 2 + 3 files changed, 241 insertions(+) create mode 100644 meta/recipes-support/vim/files/CVE-2026-28420.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-46483.patch diff --git a/meta/recipes-support/vim/files/CVE-2026-28420.patch b/meta/recipes-support/vim/files/CVE-2026-28420.patch new file mode 100644 index 0000000000..f5b2f42f6a --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-28420.patch @@ -0,0 +1,162 @@ +From bb6de2105b160e729c340631435cd62f3e69bd32 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Mon, 23 Feb 2026 20:29:43 +0000 +Subject: [PATCH] patch 9.2.0076: [security]: buffer-overflow in terminal + handling + +Problem: When processing terminal output with many combining characters + from supplementary planes (4-byte UTF-8), a heap-buffer + overflow occurs. Additionally, the loop iterating over + cell characters can read past the end of the vterm array + (ehdgks0627, un3xploitable). +Solution: Use VTERM_MAX_CHARS_PER_CELL * 4 for ga_grow() to ensure + sufficient space. Add a boundary check to the character + loop to prevent index out-of-bounds access. + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-rvj2-jrf9-2phg + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/bb6de2105b160e729c340631435cd62f3e69bd32] +CVE: CVE-2026-28420 +Signed-off-by: Hitendra Prajapati +--- + src/terminal.c | 5 +- + .../samples/terminal_max_combining_chars.txt | 80 +++++++++++++++++++ + src/testdir/test_terminal3.vim | 14 ++++ + 3 files changed, 97 insertions(+), 2 deletions(-) + create mode 100644 src/testdir/samples/terminal_max_combining_chars.txt + +diff --git a/src/terminal.c b/src/terminal.c +index 921b234..78990ac 100644 +--- a/src/terminal.c ++++ b/src/terminal.c +@@ -3533,12 +3533,13 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user) + { + for (col = 0; col < len; col += cells[col].width) + { +- if (ga_grow(&ga, MB_MAXBYTES) == FAIL) ++ if (ga_grow(&ga, VTERM_MAX_CHARS_PER_CELL * 4) == FAIL) + { + ga.ga_len = 0; + break; + } +- for (i = 0; (c = cells[col].chars[i]) > 0 || i == 0; ++i) ++ for (i = 0; i < VTERM_MAX_CHARS_PER_CELL && ++ ((c = cells[col].chars[i]) > 0 || i == 0); ++i) + ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c, + (char_u *)ga.ga_data + ga.ga_len); + cell2cellattr(&cells[col], &p[col]); +diff --git a/src/testdir/samples/terminal_max_combining_chars.txt b/src/testdir/samples/terminal_max_combining_chars.txt +new file mode 100644 +index 0000000..a4f508d +--- /dev/null ++++ b/src/testdir/samples/terminal_max_combining_chars.txt +@@ -0,0 +1,80 @@ ++padding line 000 ++padding line 001 ++padding line 002 ++padding line 003 ++padding line 004 ++padding line 005 ++padding line 006 ++padding line 007 ++padding line 008 ++padding line 009 ++padding line 010 ++padding line 011 ++padding line 012 ++padding line 013 ++padding line 014 ++padding line 015 ++padding line 016 ++padding line 017 ++padding line 018 ++padding line 019 ++padding line 020 ++padding line 021 ++padding line 022 ++padding line 023 ++padding line 024 ++padding line 025 ++padding line 026 ++padding line 027 ++padding line 028 ++padding line 029 ++padding line 030 ++padding line 031 ++padding line 032 ++padding line 033 ++padding line 034 ++padding line 035 ++padding line 036 ++padding line 037 ++padding line 038 ++padding line 039 ++padding line 040 ++padding line 041 ++padding line 042 ++padding line 043 ++padding line 044 ++padding line 045 ++padding line 046 ++padding line 047 ++padding line 048 ++padding line 049 ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA From patchwork Tue Jun 30 07:18:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 91337 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8577BC43602 for ; Tue, 30 Jun 2026 07:19:30 +0000 (UTC) Received: from mail-dy1-f171.google.com (mail-dy1-f171.google.com [74.125.82.171]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.15496.1782803969190350901 for ; Tue, 30 Jun 2026 00:19:29 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=Heou2TvR; spf=pass (domain: mvista.com, ip: 74.125.82.171, mailfrom: hprajapati@mvista.com) Received: by mail-dy1-f171.google.com with SMTP id 5a478bee46e88-30df5854e1eso292275eec.0 for ; Tue, 30 Jun 2026 00:19:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1782803968; x=1783408768; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iY8sNDvAFtpbfV6DQH7SC1m/Gsy2djm5Ftv0DkLuE88=; b=Heou2TvRxc1Aav4oJFe5vaPnGR0yhM+LI3QoqwbZ+8FdtbQOwRmwAHmlMJ1Guv6ScL YVzl37hkXH0Dl0n3oXPblC++1skcBy+kvzxW6VqKhrjxAbXxfQcQkjrnuVMB3L9o4UgD lWyVTyTaFNxQELcipm8ghpGRLtb6kzjQRWncw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782803968; x=1783408768; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=iY8sNDvAFtpbfV6DQH7SC1m/Gsy2djm5Ftv0DkLuE88=; b=Sl9f6Md4jcCui0Fb+ZqEfPozwDBPDNHws+BKx1T3zEx0t6kz8LycWEQ8r1itnA4XDx MHGz5KeDkwtiFgLyNrn2awfuNOZeWciFYH+RW4xWS1j8xLBioxJaRYVGfse8DrRZfrAP 7u0nio9cLYgRa5imaKA0zF1ug5nLmtjT77E6cP5JbHLFLRs2VJ3ebZewzn1FaMmxDMk4 IJkhO7mPdbqObEb4yqHYr8oD4TsY7WxvJbBzzDPIbfOuDFdKo2UZsIridDrSa7om3Rz0 /+/oeJ0R+MMb4Iybx1W7wjBgBkZpoEfpzRgyybZ5HP/YeaO7qOuK4r/sK9uHMWb84iRa uZww== X-Gm-Message-State: AOJu0Yweed9Pyqn7VAA7v/h+xEw0p85NpsqCZNhprBI1YZ+kocbW+Bey 8URdR1WmjOpBSDx6g/U2DmS7NH4QhZS4JlO26RVo5jomFdmaZg80vcGU6SHAxGe6a+CLGuKWkaJ 74BC1dFE= X-Gm-Gg: AfdE7clIGg+nZRg+05PvL1zFA6JykX75iMPLFFLcWpr+5if8K2P9MEK03jJmPBqxE9m kOuDukUMS6c964sjCULUXXgefE9VvyoAzwelslma3LlemzwqZhRBUWlHybbLQDjw0QUqqyxrEPt QnNPgSIO911oQuOA7UU1HyiBaNdIDHQ9Q4vD4EntOyrgUJ4WUENr4SJ1+bSBXMRqsjfhs8y9q/m AZGavBD7NVmdTiBUntUceWA504brgPbv9cTxpsj6cIqNbscPwui39NrUH3mHX3Txnf8+rJW554q W+KCJTlI/aYHkRgi3WBgklAz4CUgyafZiOT6/8emLmYeZwy/v2haZLxblmw4n19sFaTzD/gcjVm 35t6racCu6sUk9wRBhHRRMRl6d/2/eBCYve44bdeTSxE4vPdC9r7IP5DsU9j4NZjIAVGLhNwef+ 4VO5As8d/whgeu9NGAbZAa0Qpkrw== X-Received: by 2002:a05:7300:8ca4:b0:30c:ab96:7306 with SMTP id 5a478bee46e88-30eea0e9753mr592693eec.22.1782803967981; Tue, 30 Jun 2026 00:19:27 -0700 (PDT) Received: from MVIN00013.mvista.com ([103.250.136.242]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30ee2fb6514sm4311038eec.7.2026.06.30.00.19.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:19:27 -0700 (PDT) From: Hitendra Prajapati To: openembedded-core@lists.openembedded.org Cc: Hitendra Prajapati Subject: [scarthgap][PATCHv2 5/5] vim: Fix for CVE-2026-52858,CVE-2026-52859,CVE-2026-52860 Date: Tue, 30 Jun 2026 12:48:59 +0530 Message-ID: <20260630071903.155470-5-hprajapati@mvista.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260630071903.155470-1-hprajapati@mvista.com> References: <20260630071903.155470-1-hprajapati@mvista.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 30 Jun 2026 07:19:30 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/239858 Pick patch from [1], [2] & [3] also mentioned at NVD report in [4,5 & 6] [1] https://github.com/vim/vim/commit/4b850457e12e1a678dd209f2868154f7553cbf8d [2] https://github.com/vim/vim/commit/63680c6d3d52477817b49cd1a66e7aabe8a7aa19 [3] https://github.com/vim/vim/commit/c8c63673bc4253212820626aeeb75999d9a539d2 [4] https://nvd.nist.gov/vuln/detail/CVE-2026-52858 [5] https://nvd.nist.gov/vuln/detail/CVE-2026-52859 [6] https://nvd.nist.gov/vuln/detail/CVE-2026-52860 Signed-off-by: Hitendra Prajapati --- .../vim/files/CVE-2026-52858.patch | 167 +++++++ .../vim/files/CVE-2026-52859.patch | 274 +++++++++++ .../vim/files/CVE-2026-52860.patch | 446 ++++++++++++++++++ meta/recipes-support/vim/vim.inc | 3 + 4 files changed, 890 insertions(+) create mode 100644 meta/recipes-support/vim/files/CVE-2026-52858.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-52859.patch create mode 100644 meta/recipes-support/vim/files/CVE-2026-52860.patch diff --git a/meta/recipes-support/vim/files/CVE-2026-52858.patch b/meta/recipes-support/vim/files/CVE-2026-52858.patch new file mode 100644 index 0000000000..7e036e45ea --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-52858.patch @@ -0,0 +1,167 @@ +From 4b850457e12e1a678dd209f2868154f7553cbf8d Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Fri, 29 May 2026 19:05:53 +0000 +Subject: [PATCH] patch 9.2.0561: [security]: possible code execution with + python3complete + +Problem: [security]: possible code execution with python3complete +Solution: Disable execution of import/from statements + +Github Security Advisory: +https://github.com/vim/vim/security/advisories/GHSA-52mc-rq6p-rc7c + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/4b850457e12e1a678dd209f2868154f7553cbf8d] +CVE: CVE-2026-52858 +Signed-off-by: Hitendra Prajapati +--- + runtime/autoload/README.txt | 1 + + runtime/autoload/python3complete.vim | 17 ++++++++++++++--- + runtime/autoload/pythoncomplete.vim | 17 ++++++++++++++--- + runtime/doc/filetype.txt | 15 ++++++++++++++- + 4 files changed, 43 insertions(+), 7 deletions(-) + +diff --git a/runtime/autoload/README.txt b/runtime/autoload/README.txt +index 3b18d3d..b225819 100644 +--- a/runtime/autoload/README.txt ++++ b/runtime/autoload/README.txt +@@ -17,6 +17,7 @@ htmlcomplete.vim HTML + javascriptcomplete.vim Javascript + phpcomplete.vim PHP + pythoncomplete.vim Python ++python3complete.vim Python + rubycomplete.vim Ruby + syntaxcomplete.vim from syntax highlighting + xmlcomplete.vim XML (uses files in the xml directory) +diff --git a/runtime/autoload/python3complete.vim b/runtime/autoload/python3complete.vim +index ea0a331..aba3412 100644 +--- a/runtime/autoload/python3complete.vim ++++ b/runtime/autoload/python3complete.vim +@@ -14,6 +14,10 @@ + " i.e. "import url" + " Continue parsing on invalid line?? + " ++" v 0.10 by Vim project ++" * disables importing local modules, unless the global Vim variable ++" g:pythoncomplete_allow_import is set to non-zero ++" + " v 0.9 + " * Fixed docstring parsing for classes and functions + " * Fixed parsing of *args and **kwargs type arguments +@@ -132,11 +136,20 @@ class Completer(object): + + def evalsource(self,text,line=0): + sc = self.parser.parse(text,line) ++ try: allow_imports = int( ++ vim.eval("get(g:, 'pythoncomplete_allow_import', 0)")) ++ except Exception: ++ allow_imports = 0 + src = sc.get_code() + dbg("source: %s" % src) + try: exec(src,self.compldict) + except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1])) + for l in sc.locals: ++ # Executing import/from statements harvested from the buffer runs ++ # arbitrary package code; only do so when the user opted in. ++ if not allow_imports and (l.startswith('import') ++ or l.startswith('from ')): ++ continue + try: exec(l,self.compldict) + except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) + +@@ -300,13 +313,11 @@ class Scope(object): + def get_code(self): + str = "" + if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n' +- for l in self.locals: +- if l.startswith('import'): str += l+'\n' + str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' + for sub in self.subscopes: + str += sub.get_code() + for l in self.locals: +- if not l.startswith('import'): str += l+'\n' ++ if not l.startswith('import') and not l.startswith('from '): str += l+'\n' + + return str + +diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim +index aa28bb7..1014776 100644 +--- a/runtime/autoload/pythoncomplete.vim ++++ b/runtime/autoload/pythoncomplete.vim +@@ -12,6 +12,10 @@ + " i.e. "import url" + " Continue parsing on invalid line?? + " ++" v 0.10 by Vim project ++" * disables importing local modules, unless the global Vim variable ++" g:pythoncomplete_allow_import is set to non-zero ++" + " v 0.9 + " * Fixed docstring parsing for classes and functions + " * Fixed parsing of *args and **kwargs type arguments +@@ -146,11 +150,20 @@ class Completer(object): + + def evalsource(self,text,line=0): + sc = self.parser.parse(text,line) ++ try: allow_imports = int( ++ vim.eval("get(g:, 'pythoncomplete_allow_import', 0)")) ++ except Exception: ++ allow_imports = 0 + src = sc.get_code() + dbg("source: %s" % src) + try: exec(src) in self.compldict + except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1])) + for l in sc.locals: ++ # Executing import/from statements harvested from the buffer runs ++ # arbitrary package code; only do so when the user opted in. ++ if not allow_imports and (l.startswith('import') ++ or l.startswith('from ')): ++ continue + try: exec(l) in self.compldict + except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) + +@@ -315,13 +328,11 @@ class Scope(object): + def get_code(self): + str = "" + if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n' +- for l in self.locals: +- if l.startswith('import'): str += l+'\n' + str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' + for sub in self.subscopes: + str += sub.get_code() + for l in self.locals: +- if not l.startswith('import'): str += l+'\n' ++ if not l.startswith('import') and not l.startswith('from '): str += l+'\n' + + return str + +diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt +index 597141d..c8572fe 100644 +--- a/runtime/doc/filetype.txt ++++ b/runtime/doc/filetype.txt +@@ -739,7 +739,20 @@ By default the following options are set, in accordance with PEP8: > + To disable this behavior, set the following variable in your vimrc: > + + let g:python_recommended_style = 0 +- ++< ++Python omni-completion |compl-omni| is provided by python3complete.vim (or ++pythoncomplete.vim) for Vim builds with the |+python|/|+python3| interpreter. ++By default it does not inspect the import / from statements found in the ++buffer. This means completion of names defined in the buffer itself (classes, ++functions, variables) works, but completion of members of imported modules is ++not offered. ++ ++To enable completion of imported module members, set: > ++ let g:pythoncomplete_allow_import = 1 ++< ++WARNING: enabling this causes omni-completion to execute the import statements ++found in the buffer through Python's import machinery, which runs the imported ++modules' top-level code. Only enable this for code you trust. + + QF QUICKFIX *qf.vim* *ft-qf-plugin* + +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-52859.patch b/meta/recipes-support/vim/files/CVE-2026-52859.patch new file mode 100644 index 0000000000..472d7c0640 --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-52859.patch @@ -0,0 +1,274 @@ +From 63680c6d3d52477817b49cd1a66e7aabe8a7aa19 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Sat, 30 May 2026 16:34:40 +0000 +Subject: [PATCH] patch 9.2.0565: [security]: out-of-bounds read in + update_snapshot() + +Problem: Out-of-bounds read in update_snapshot() when a terminal cell + fills all VTERM_MAX_CHARS_PER_CELL slots (a base character + plus five combining marks): the loop over cell.chars[] has no + upper bound and libvterm leaves the array unterminated when full, so + it reads past the array and appends out-of-bounds values to a + buffer sized for only VTERM_MAX_CHARS_PER_CELL characters. +Solution: Bound the loop with i < VTERM_MAX_CHARS_PER_CELL, mirroring + the loop in handle_pushline() (Christian Brabandt). + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/63680c6d3d52477817b49cd1a66e7aabe8a7aa19] +CVE: CVE-2026-52859 +Signed-off-by: Hitendra Prajapati +--- + src/terminal.c | 3 +- + src/testdir/samples/combining_chars.txt | 200 ++++++++++++++++++++++++ + src/testdir/test_terminal3.vim | 15 ++ + 3 files changed, 217 insertions(+), 1 deletion(-) + create mode 100644 src/testdir/samples/combining_chars.txt + +diff --git a/src/terminal.c b/src/terminal.c +index 78990ac..527f1b9 100644 +--- a/src/terminal.c ++++ b/src/terminal.c +@@ -2080,7 +2080,8 @@ update_snapshot(term_T *term) + int i; + int c; + +- for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i) ++ for (i = 0; i < VTERM_MAX_CHARS_PER_CELL && ++ ((c = cell.chars[i]) > 0 || i == 0); ++i) + ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c, + (char_u *)ga.ga_data + ga.ga_len); + } +diff --git a/src/testdir/samples/combining_chars.txt b/src/testdir/samples/combining_chars.txt +new file mode 100644 +index 0000000..d9a3c17 +--- /dev/null ++++ b/src/testdir/samples/combining_chars.txt +@@ -0,0 +1,200 @@ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ ++á́́́́ጁ +diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim +index cb1946f..c02801e 100644 +--- a/src/testdir/test_terminal3.vim ++++ b/src/testdir/test_terminal3.vim +@@ -1051,4 +1051,19 @@ func Test_terminal_max_combining_chars() + exe buf . "bwipe!" + endfunc + ++func Test_terminal_output_combining_chars() ++ CheckUnix ++ new ++ let cmd = "cat samples/combining_chars.txt" ++ let buf = term_start(cmd, {'curwin': 1, 'term_finish': 'open', 'term_rows': 10, 'term_cols': 30}) ++ call WaitForAssert({-> assert_match('finished', term_getstatus(buf))}) ++ call TermWait(buf) ++ let lines = getbufline(buf, 1, '$') ++ " get byte lengths to confirm combining chars present ++ let lens = map(copy(lines), 'len(v:val)') ++ let expected = repeat([11], 190) + repeat([14], 10) ++ call assert_equal(expected, lens) ++ bw! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/files/CVE-2026-52860.patch b/meta/recipes-support/vim/files/CVE-2026-52860.patch new file mode 100644 index 0000000000..52a18415ce --- /dev/null +++ b/meta/recipes-support/vim/files/CVE-2026-52860.patch @@ -0,0 +1,446 @@ +From c8c63673bc4253212820626aeeb75999d9a539d2 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Thu, 4 Jun 2026 21:06:09 +0000 +Subject: [PATCH] patch 9.2.0597: [security]: possible code execution with + python complete + +Problem: [security]: another possible code execution with python complete + (David Carliez) +Solution: Strip default expressions and annotations from generated + source for pythoncomplete and python3complete. + +Github Security Advisory: +https://github.com/vim/vim/security/advisories/GHSA-65p9-mwwx-7468 + +Signed-off-by: Christian Brabandt + +Upstream-Status: Backport [https://github.com/vim/vim/commit/c8c63673bc4253212820626aeeb75999d9a539d2] +CVE: CVE-2026-52860 +Signed-off-by: Hitendra Prajapati +--- + runtime/autoload/python3complete.vim | 43 +++- + runtime/autoload/pythoncomplete.vim | 43 +++- + src/testdir/Make_all.mak | 2 + + src/testdir/test_plugin_python3complete.vim | 224 ++++++++++++++++++++ + 4 files changed, 304 insertions(+), 8 deletions(-) + create mode 100644 src/testdir/test_plugin_python3complete.vim + +diff --git a/runtime/autoload/python3complete.vim b/runtime/autoload/python3complete.vim +index aba3412..a031424 100644 +--- a/runtime/autoload/python3complete.vim ++++ b/runtime/autoload/python3complete.vim +@@ -1,8 +1,8 @@ + "python3complete.vim - Omni Completion for python + " Maintainer: + " Previous Maintainer: Aaron Griffin +-" Version: 0.9 +-" Last Updated: 2022 Mar 30 ++" Version: 0.10 ++" Last Updated: 2026 Jun 04 + " + " Roland Puntaier: this file contains adaptations for python3 and is parallel to pythoncomplete.vim + " +@@ -17,6 +17,11 @@ + " v 0.10 by Vim project + " * disables importing local modules, unless the global Vim variable + " g:pythoncomplete_allow_import is set to non-zero ++" * strip default values and annotations from function parameter lists ++" before exec(), and whitelist class base lists to dotted names: the ++" previous code passed buffer-supplied expressions to exec() which ++" Python evaluates at definition time, allowing arbitrary code ++" execution via crafted def/class headers + " + " v 0.9 + " * Fixed docstring parsing for classes and functions +@@ -100,6 +105,24 @@ warnings.simplefilter(action='ignore', category=FutureWarning) + + import sys, tokenize, io, types + from token import NAME, DEDENT, NEWLINE, STRING ++import re ++ ++# Used by Class.get_code(): a base class expression is only included in the ++# code passed to exec() if it is a pure dotted name (e.g. "Base", "mod.Base", ++# "pkg.sub.Cls"). Anything containing calls, subscripts, "=", ":" or other ++# operators is dropped, since exec()-ing it would evaluate buffer-supplied ++# expressions. See the security note in the file header. ++_DOTTED_NAME_RE = re.compile(r'^[A-Za-z_]\w*(\s*\.\s*[A-Za-z_]\w*)*$') ++ ++def _strip_param(p): ++ # Return the bare parameter name from a parameter spec harvested by ++ # _parenparse(), discarding any default value or annotation. Default ++ # values and annotations would otherwise be evaluated by exec() at ++ # function-definition time. Star prefixes ("*args", "**kw") and bare ++ # "*" / "/" are preserved as written. ++ p = p.split('=', 1)[0] ++ p = p.split(':', 1)[0] ++ return p.strip() + + debugstmts=[] + def dbg(s): debugstmts.append(s) +@@ -347,7 +370,13 @@ class Class(Scope): + return c + def get_code(self): + str = '%sclass %s' % (self.currentindent(),self.name) +- if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers) ++ # Only include base class expressions that are pure dotted names. ++ # Anything else (calls, subscripts, conditionals, ...) is dropped ++ # because exec() would evaluate it at class-definition time. See ++ # the security note in the file header. ++ safe_supers = [s.strip() for s in self.supers ++ if _DOTTED_NAME_RE.match(s.strip())] ++ if len(safe_supers) > 0: str += '(%s)' % ','.join(safe_supers) + str += ':\n' + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + if len(self.subscopes) > 0: +@@ -364,8 +393,14 @@ class Function(Scope): + def copy_decl(self,indent=0): + return Function(self.name,self.params,indent, self.docstr) + def get_code(self): ++ # Strip default values and annotations from each parameter before ++ # joining: exec() evaluates these at definition time and a hostile ++ # buffer could otherwise execute arbitrary code via crafted def ++ # headers. See file header for details. ++ safe_params = [_strip_param(p) for p in self.params] ++ safe_params = [p for p in safe_params if p] + str = "%sdef %s(%s):\n" % \ +- (self.currentindent(),self.name,','.join(self.params)) ++ (self.currentindent(),self.name,','.join(safe_params)) + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + str += "%spass\n" % self.childindent() + return str +diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim +index 1014776..39b1efd 100644 +--- a/runtime/autoload/pythoncomplete.vim ++++ b/runtime/autoload/pythoncomplete.vim +@@ -1,8 +1,8 @@ + "pythoncomplete.vim - Omni Completion for python + " Maintainer: + " Previous Maintainer: Aaron Griffin +-" Version: 0.9 +-" Last Updated: 2020 Oct 9 ++" Version: 0.10 ++" Last Updated: 2026 Jun 04 + " + " Changes + " TODO: +@@ -15,6 +15,11 @@ + " v 0.10 by Vim project + " * disables importing local modules, unless the global Vim variable + " g:pythoncomplete_allow_import is set to non-zero ++" * strip default values and annotations from function parameter lists ++" before exec(), and whitelist class base lists to dotted names: the ++" previous code passed buffer-supplied expressions to exec() which ++" Python evaluates at definition time, allowing arbitrary code ++" execution via crafted def/class headers + " + " v 0.9 + " * Fixed docstring parsing for classes and functions +@@ -95,6 +100,24 @@ function! s:DefPython() + python << PYTHONEOF + import sys, tokenize, cStringIO, types + from token import NAME, DEDENT, NEWLINE, STRING ++import re ++ ++# Used by Class.get_code(): a base class expression is only included in the ++# code passed to exec() if it is a pure dotted name (e.g. "Base", "mod.Base", ++# "pkg.sub.Cls"). Anything containing calls, subscripts, "=", ":" or other ++# operators is dropped, since exec()-ing it would evaluate buffer-supplied ++# expressions. See the security note in the file header. ++_DOTTED_NAME_RE = re.compile(r'^[A-Za-z_]\w*(\s*\.\s*[A-Za-z_]\w*)*$') ++ ++def _strip_param(p): ++ # Return the bare parameter name from a parameter spec harvested by ++ # _parenparse(), discarding any default value or annotation. Default ++ # values and annotations would otherwise be evaluated by exec() at ++ # function-definition time. Star prefixes ("*args", "**kw") and bare ++ # "*" / "/" are preserved as written. ++ p = p.split('=', 1)[0] ++ p = p.split(':', 1)[0] ++ return p.strip() + + debugstmts=[] + def dbg(s): debugstmts.append(s) +@@ -362,7 +385,13 @@ class Class(Scope): + return c + def get_code(self): + str = '%sclass %s' % (self.currentindent(),self.name) +- if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers) ++ # Only include base class expressions that are pure dotted names. ++ # Anything else (calls, subscripts, conditionals, ...) is dropped ++ # because exec() would evaluate it at class-definition time. See ++ # the security note in the file header. ++ safe_supers = [s.strip() for s in self.supers ++ if _DOTTED_NAME_RE.match(s.strip())] ++ if len(safe_supers) > 0: str += '(%s)' % ','.join(safe_supers) + str += ':\n' + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + if len(self.subscopes) > 0: +@@ -379,8 +408,14 @@ class Function(Scope): + def copy_decl(self,indent=0): + return Function(self.name,self.params,indent, self.docstr) + def get_code(self): ++ # Strip default values and annotations from each parameter before ++ # joining: exec() evaluates these at definition time and a hostile ++ # buffer could otherwise execute arbitrary code via crafted def ++ # headers. See file header for details. ++ safe_params = [_strip_param(p) for p in self.params] ++ safe_params = [p for p in safe_params if p] + str = "%sdef %s(%s):\n" % \ +- (self.currentindent(),self.name,','.join(self.params)) ++ (self.currentindent(),self.name,','.join(safe_params)) + if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n' + str += "%spass\n" % self.childindent() + return str +diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak +index 0d4aeb0..87545b7 100644 +--- a/src/testdir/Make_all.mak ++++ b/src/testdir/Make_all.mak +@@ -247,6 +247,7 @@ NEW_TESTS = \ + test_plugin_helptoc \ + test_plugin_man \ + test_plugin_matchparen \ ++ test_plugin_python3complete \ + test_plugin_tar \ + test_plugin_termdebug \ + test_plugin_tohtml \ +@@ -520,6 +521,7 @@ NEW_TESTS_RES = \ + test_plugin_helptoc.res \ + test_plugin_man.res \ + test_plugin_matchparen.res \ ++ test_plugin_python3complete.res \ + test_plugin_tar.res \ + test_plugin_termdebug.res \ + test_plugin_tohtml.res \ +diff --git a/src/testdir/test_plugin_python3complete.vim b/src/testdir/test_plugin_python3complete.vim +new file mode 100644 +index 0000000..e2b0c66 +--- /dev/null ++++ b/src/testdir/test_plugin_python3complete.vim +@@ -0,0 +1,224 @@ ++" Tests for the Python omni-completion plugin (runtime/autoload/python3complete.vim). ++" ++CheckFeature python3 ++ ++" Run omni-completion against the given buffer contents and assert that the ++" marker file was not created. Pre-patch behaviour exec()s reconstructed ++" def/class headers, which evaluates the buffer-supplied expression and ++" creates the marker file. Post-patch, the expressions are stripped. ++func s:CompleteAndExpectNoMarker(buffer_lines, marker_path, msg) ++ call delete(a:marker_path) ++ defer delete(a:marker_path) ++ let g:pythoncomplete_allow_import = 0 ++ new ++ setfiletype python ++ call setline(1, a:buffer_lines) ++ call cursor(line('$'), col([line('$'), '$'])) ++ ++ " The PoC trigger -- direct invocation of the omnifunc with an empty base. ++ " This is the same path Vim takes for CTRL-X CTRL-O. ++ silent! call python3complete#Complete(0, '') ++ ++ call assert_false(filereadable(a:marker_path), ++ \ a:msg . ' (marker ' . a:marker_path . ' was created)') ++ ++ bwipe! ++ unlet! g:pythoncomplete_allow_import ++endfunc ++ ++func Test_python3complete_no_exec_via_function_default() ++ let marker = tempname() ++ call s:CompleteAndExpectNoMarker([ ++ \ 'def f(x=open(' . string(marker) . ', "w").close()):', ++ \ ' pass', ++ \ 'f.', ++ \ ], marker, ++ \ 'function default expression was evaluated during omni-completion') ++endfunc ++ ++func Test_python3complete_no_exec_via_function_annotation() ++ let marker = tempname() ++ call s:CompleteAndExpectNoMarker([ ++ \ 'def f(x: open(' . string(marker) . ', "w").close()):', ++ \ ' pass', ++ \ 'f.', ++ \ ], marker, ++ \ 'function annotation expression was evaluated during omni-completion') ++endfunc ++ ++func Test_python3complete_no_exec_via_class_base() ++ let marker = tempname() ++ " "or object" gives the class a valid base after the side-effecting ++ " open().close() expression returns None. Without "or object" the ++ " exec would raise TypeError, but the file would still be created ++ " before the exception -- the assertion would still hold. Using ++ " "or object" keeps the buffer parseable as valid Python. ++ call s:CompleteAndExpectNoMarker([ ++ \ 'class Foo(open(' . string(marker) . ', "w").close() or object):', ++ \ ' pass', ++ \ 'Foo.', ++ \ ], marker, ++ \ 'class base expression was evaluated during omni-completion') ++endfunc ++ ++func Test_python3complete_no_exec_with_multiple_params() ++ " The strip must apply to every parameter, not just the first. ++ let marker = tempname() ++ call s:CompleteAndExpectNoMarker([ ++ \ 'def f(a, b=1, c=open(' . string(marker) . ', "w").close(), d=2):', ++ \ ' pass', ++ \ 'f.', ++ \ ], marker, ++ \ 'non-first parameter default was evaluated during omni-completion') ++endfunc ++ ++func Test_python3complete_no_exec_via_starargs_default() ++ " "*args" and "**kw" must still be preserved after stripping; ensure a ++ " default following them is also stripped. ++ let marker = tempname() ++ call s:CompleteAndExpectNoMarker([ ++ \ 'def f(*args, key=open(' . string(marker) . ', "w").close(), **kw):', ++ \ ' pass', ++ \ 'f.', ++ \ ], marker, ++ \ 'keyword-only default after *args was evaluated during omni-completion') ++endfunc ++ ++func Test_python3complete_normal_completion_still_works() ++ " Positive control: completion against a buffer with a legitimate class ++ " must still produce completion items. The stripping logic should not ++ " break the normal completion path. ++ let g:pythoncomplete_allow_import = 0 ++ ++ new ++ setfiletype python ++ call setline(1, [ ++ \ 'class MyHelper:', ++ \ ' def alpha(self): pass', ++ \ ' def beta(self): pass', ++ \ 'h = MyHelper()', ++ \ 'h.', ++ \ ]) ++ call cursor(5, 3) ++ ++ " First call returns the column to start completion at; second returns ++ " the list of completion items. ++ let start = python3complete#Complete(1, '') ++ call assert_true(start >= 0, ++ \ 'python3complete#Complete(1, "") returned ' . start) ++ ++ let items = python3complete#Complete(0, '') ++ " Items should be a list (possibly empty if the parser can't resolve "h", ++ " but should not be a parse error from our stripping changes). ++ call assert_equal(type([]), type(items), ++ \ 'python3complete#Complete(0, "") did not return a list') ++ ++ bwipe! ++ unlet! g:pythoncomplete_allow_import ++endfunc ++ ++func Test_python3complete_inherited_completion_via_dotted_base() ++ " Positive control for the class-base whitelist: a dotted-name base class ++ " (the common, safe case) must still be carried into the reconstructed ++ " source so that completion on a subclass can resolve inherited members. ++ let g:pythoncomplete_allow_import = 0 ++ ++ new ++ setfiletype python ++ call setline(1, [ ++ \ 'class Base:', ++ \ ' def shared(self): pass', ++ \ 'class Derived(Base):', ++ \ ' def own(self): pass', ++ \ 'd = Derived()', ++ \ 'd.', ++ \ ]) ++ call cursor(6, 3) ++ ++ let items = python3complete#Complete(0, '') ++ call assert_equal(type([]), type(items), ++ \ 'completion against a subclass with a dotted base did not return a list') ++ ++ bwipe! ++ unlet! g:pythoncomplete_allow_import ++endfunc ++ ++" Build a tiny Python module that creates a marker file as a side effect of ++" being imported, add its directory to sys.path, run omni-completion against ++" a buffer containing `import vimtest_marker_mod`, and report whether the ++" marker file was created. Used by the two allow_import tests below. ++func s:RunImportCompletion(allow_import_value) ++ let g:pythoncomplete_allow_import = a:allow_import_value ++ let marker = tempname() ++ let module_dir = tempname() ++ call mkdir(module_dir, 'R') ++ ++ call writefile([ ++ \ 'open(' . string(marker) . ', "w").close()', ++ \ ], module_dir . '/vimtest_marker_mod.py') ++ ++ defer delete(marker) ++ ++ " Pass module_dir to Python via a g: variable so vim.eval() can read it. ++ let g:pythoncomplete_test_module_dir = module_dir ++ py3 << EOF ++import sys, vim ++_p = vim.eval('g:pythoncomplete_test_module_dir') ++if _p not in sys.path: ++ sys.path.insert(0, _p) ++# Drop any cached copy so the module body re-runs and the marker side ++# effect fires on import. ++sys.modules.pop('vimtest_marker_mod', None) ++EOF ++ ++ new ++ setfiletype python ++ call setline(1, [ ++ \ 'import vimtest_marker_mod', ++ \ 'vimtest_marker_mod.', ++ \ ]) ++ call cursor(2, 2) ++ ++ silent! call python3complete#Complete(0, '') ++ ++ let ran = filereadable(marker) ++ ++ bwipe! ++ unlet g:pythoncomplete_allow_import ++ ++ " Teardown: restore sys.path, drop the cached module so a subsequent ++ " test run starts clean, clean up the temp module dir. ++ py3 << EOF ++import sys, vim ++_p = vim.eval('g:pythoncomplete_test_module_dir') ++if _p in sys.path: ++ sys.path.remove(_p) ++sys.modules.pop('vimtest_marker_mod', None) ++EOF ++ unlet g:pythoncomplete_test_module_dir ++ call delete(module_dir, 'rf') ++ call delete(marker) ++ unlet! g:pythoncomplete_allow_import ++ ++ return ran ++endfunc ++ ++func Test_python3complete_allow_import_off_blocks_imports() ++ " GHSA-52mc-rq6p-rc7c mitigation: with the default flag value (0), an ++ " `import` line harvested from the buffer must NOT be exec()'d. The ++ " marker module's side effect (creating a file when its body runs) is ++ " the observable proof that the exec did or did not happen. ++ call assert_false(s:RunImportCompletion(0), ++ \ 'g:pythoncomplete_allow_import=0 did not block the buffer import') ++endfunc ++ ++func Test_python3complete_allow_import_on_runs_imports() ++ " Symmetric positive control: with the flag set to non-zero, the harvested ++ " import IS exec()'d and the module loads. Without this control the ++ " negative test above could pass for unrelated reasons (e.g. completion ++ " failing to parse the buffer at all). ++ call assert_true(s:RunImportCompletion(1), ++ \ 'g:pythoncomplete_allow_import=1 did not run the buffer import') ++endfunc ++ ++" vim: shiftwidth=2 sts=2 expandtab +-- +2.34.1 + diff --git a/meta/recipes-support/vim/vim.inc b/meta/recipes-support/vim/vim.inc index 9a4b21f530..d69a337b4e 100644 --- a/meta/recipes-support/vim/vim.inc +++ b/meta/recipes-support/vim/vim.inc @@ -33,6 +33,9 @@ SRC_URI = "git://github.com/vim/vim.git;branch=master;protocol=https \ file://CVE-2026-45130.patch \ file://CVE-2026-46483.patch \ file://CVE-2026-28420.patch \ + file://CVE-2026-52858.patch \ + file://CVE-2026-52859.patch \ + file://CVE-2026-52860.patch \ " PV .= ".1683"