patch 9.2.0495: [security]: runtime(netrw): code injection via NetrwBookHistSave()

Problem:  [security]: runtime(netrw): code injection via
          NetrwBookHistSave()
Solution: Properly quote the directory name using string() function
          (Srinivas Piskala Ganesh Babu)

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-crm5-rh6j-2c7c

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-05-17 18:53:48 +00:00
parent 2a01e59671
commit f08ab2f4d7
3 changed files with 24 additions and 2 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
" Creator: Charles E Campbell
" Previous Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
" Maintainer: This runtime file is looking for a new maintainer.
" Last Change: 2026 May 14
" Last Change: 2026 May 17
" 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
@@ -2935,7 +2935,7 @@ function s:NetrwBookHistSave()
while ( first || cnt != g:netrw_dirhistcnt )
let lastline= lastline + 1
if exists("g:netrw_dirhist_{cnt}")
call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
call setline(lastline,'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt}))
endif
let first = 0
let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
+20
View File
@@ -760,4 +760,24 @@ function Test_netrw_NetrwMaps_CR_dirname()
unlet! g:netrw_pwn
bw!
endfunction
func Test_netrw_injection()
let g:netrw_home = getcwd()
let savefile = g:netrw_home . '/.netrwhist'
let g:netrw_dirhistmax = 10
let g:netrw_dirhistcnt = 1
let g:netrw_dirhist_1 = "x'|let g:injected = 1|let y='z"
call delete(savefile)
try
call netrw#Call('NetrwBookHistSave')
call assert_true(filereadable(savefile), savefile . ' must be written')
unlet g:netrw_dirhist_1
execute 'source ' . fnameescape(savefile)
call assert_false(exists("g:injected"), 'injected statement must not execute')
call assert_equal("x'|let g:injected = 1|let y='z", g:netrw_dirhist_1, 'dirname must round-trip')
finally
call delete(savefile)
unlet! g:netrw_home g:netrw_dirhistmax g:netrw_dirhistcnt g:netrw_dirhist_1 g:injected
endtry
endfunc
" vim:ts=8 sts=2 sw=2 et
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
495,
/**/
494,
/**/