diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2019-04-29 19:58:53 -0400 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2019-04-29 20:47:49 -0400 |
commit | 0cecf9f121d66539be86fa76bdd7fb9221f54389 (patch) | |
tree | 0bb2a01c629b06100c189aa459215c6e94e95604 | |
parent | 63526f2eeee774c657270a1ec0cbd788480f14b7 (diff) | |
download | rneovim-0cecf9f121d66539be86fa76bdd7fb9221f54389.tar.gz rneovim-0cecf9f121d66539be86fa76bdd7fb9221f54389.tar.bz2 rneovim-0cecf9f121d66539be86fa76bdd7fb9221f54389.zip |
vim-patch:8.0.1263: others can read the swap file if a user is careless
Problem: Others can read the swap file if a user is careless with his
primary group.
Solution: If the group permission allows for reading but the world
permissions doesn't, make sure the group is right.
https://github.com/vim/vim/commit/5a73e0ca54c77e067c3b12ea6f35e3e8681e8cf8
-rw-r--r-- | src/nvim/fileio.c | 23 | ||||
-rw-r--r-- | src/nvim/testdir/test_swap.vim | 34 |
2 files changed, 54 insertions, 3 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 7abc75916c..5cd2a43a44 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -310,6 +310,7 @@ readfile ( #endif int fileformat = 0; /* end-of-line format */ int keep_fileformat = FALSE; + FileInfo file_info; int file_readonly; linenr_T skip_count = 0; linenr_T read_count = 0; @@ -481,7 +482,6 @@ readfile ( if (newfile && !read_stdin && !read_buffer && !read_fifo) { // Remember time of file. - FileInfo file_info; if (os_fileinfo((char *)fname, &file_info)) { buf_store_file_info(curbuf, &file_info); curbuf->b_mtime_read = curbuf->b_mtime; @@ -627,8 +627,25 @@ readfile ( // Set swap file protection bits after creating it. if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL && curbuf->b_ml.ml_mfp->mf_fname != NULL) { - (void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname, - (long)swap_mode); + const char *swap_fname = (const char *)curbuf->b_ml.ml_mfp->mf_fname; + + // If the group-read bit is set but not the world-read bit, then + // the group must be equal to the group of the original file. If + // we can't make that happen then reset the group-read bit. This + // avoids making the swap file readable to more users when the + // primary group of the user is too permissive. + if ((swap_mode & 044) == 040) { + FileInfo swap_info; + + if (os_fileinfo(swap_fname, &swap_info) + && file_info.stat.st_gid != swap_info.stat.st_gid + && os_fchown(curbuf->b_ml.ml_mfp->mf_fd, -1, file_info.stat.st_gid) + == -1) { + swap_mode &= 0600; + } + } + + (void)os_setperm(swap_fname, swap_mode); } #endif } diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 4dc8803a2a..a2efc8976e 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -51,6 +51,40 @@ func Test_swap_directory() call delete("Xtest.je", "rf") endfunc +func Test_swap_group() + if !has("unix") + return + endif + let groups = split(system('groups')) + if len(groups) <= 1 + throw 'Skipped: need at least two groups, got ' . groups + endif + + call delete('Xtest') + split Xtest + call setline(1, 'just some text') + wq + if system('ls -l Xtest') !~ ' ' . groups[0] . ' \d' + throw 'Skipped: test file does not have the first group' + else + silent !chmod 640 Xtest + call system('chgrp ' . groups[1] . ' Xtest') + if system('ls -l Xtest') !~ ' ' . groups[1] . ' \d' + throw 'Skipped: cannot set second group on test file' + else + split Xtest + let swapname = substitute(execute('swapname'), '[[:space:]]', '', 'g') + call assert_match('Xtest', swapname) + " Group of swapfile must now match original file. + call assert_match(' ' . groups[1] . ' \d', system('ls -l ' . swapname)) + + bwipe! + endif + endif + + call delete('Xtest') +endfunc + func Test_missing_dir() call mkdir('Xswapdir') exe 'set directory=' . getcwd() . '/Xswapdir' |