diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-11-04 21:35:01 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-11-04 21:35:01 +0100 |
commit | 5a73e0ca54c77e067c3b12ea6f35e3e8681e8cf8 (patch) | |
tree | 2e87eb6ea3c404fa035e2aebb00b4fedaeef7263 | |
parent | 7dd88c5133feda7e9ccfedcb38b6dfdba459d507 (diff) | |
download | vim-git-5a73e0ca54c77e067c3b12ea6f35e3e8681e8cf8.tar.gz |
patch 8.0.1263: others can read the swap file if a user is carelessv8.0.1263
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.
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/fileio.c | 24 | ||||
-rw-r--r-- | src/testdir/test_swap.vim | 112 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 99 insertions, 40 deletions
diff --git a/src/Makefile b/src/Makefile index e55e830ef..48487aad5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2259,6 +2259,7 @@ test_arglist \ test_stat \ test_statusline \ test_substitute \ + test_swap \ test_syn_attr \ test_syntax \ test_system \ diff --git a/src/fileio.c b/src/fileio.c index 87b85cf38..34dcdb6b5 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -716,7 +716,29 @@ 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)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode); + { + char_u *swap_fname = 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) + { + stat_T swap_st; + + if (mch_stat((char *)swap_fname, &swap_st) >= 0 + && st.st_gid != swap_st.st_gid + && fchown(curbuf->b_ml.ml_mfp->mf_fd, -1, st.st_gid) + == -1) + swap_mode &= 0600; + } + + (void)mch_setperm(swap_fname, (long)swap_mode); + } #endif } diff --git a/src/testdir/test_swap.vim b/src/testdir/test_swap.vim index 245e1f18b..d11c124d0 100644 --- a/src/testdir/test_swap.vim +++ b/src/testdir/test_swap.vim @@ -1,48 +1,82 @@ " Tests for the swap feature -" Tests for 'directory' option. -func Test_swap_directory() +"" Tests for 'directory' option. +"func Test_swap_directory() +" if !has("unix") +" return +" endif +" let content = ['start of testfile', +" \ 'line 2 Abcdefghij', +" \ 'line 3 Abcdefghij', +" \ 'end of testfile'] +" call writefile(content, 'Xtest1') +" +" " '.', swap file in the same directory as file +" set dir=.,~ +" +" " Verify that the swap file doesn't exist in the current directory +" call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1)) +" edit Xtest1 +" let swfname = split(execute("swapname"))[0] +" call assert_equal([swfname], glob(swfname, 1, 1, 1)) +" +" " './dir', swap file in a directory relative to the file +" set dir=./Xtest2,.,~ +" +" call mkdir("Xtest2") +" edit Xtest1 +" call assert_equal([], glob(swfname, 1, 1, 1)) +" let swfname = "Xtest2/Xtest1.swp" +" call assert_equal(swfname, split(execute("swapname"))[0]) +" call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1)) +" +" " 'dir', swap file in directory relative to the current dir +" set dir=Xtest.je,~ +" +" call mkdir("Xtest.je") +" call writefile(content, 'Xtest2/Xtest3') +" edit Xtest2/Xtest3 +" call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1)) +" let swfname = "Xtest.je/Xtest3.swp" +" call assert_equal(swfname, split(execute("swapname"))[0]) +" call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1)) +" +" set dir& +" call delete("Xtest1") +" call delete("Xtest2", "rf") +" call delete("Xtest.je", "rf") +"endfunc + +func Test_swap_group() if !has("unix") return endif - let content = ['start of testfile', - \ 'line 2 Abcdefghij', - \ 'line 3 Abcdefghij', - \ 'end of testfile'] - call writefile(content, 'Xtest1') - - " '.', swap file in the same directory as file - set dir=.,~ - - " Verify that the swap file doesn't exist in the current directory - call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1)) - edit Xtest1 - let swfname = split(execute("swapname"))[0] - call assert_equal([swfname], glob(swfname, 1, 1, 1)) - - " './dir', swap file in a directory relative to the file - set dir=./Xtest2,.,~ - - call mkdir("Xtest2") - edit Xtest1 - call assert_equal([], glob(swfname, 1, 1, 1)) - let swfname = "Xtest2/Xtest1.swp" - call assert_equal(swfname, split(execute("swapname"))[0]) - call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1)) + let groups = split(system('groups')) + if len(groups) <= 1 + throw 'Skipped: need at least two groups, got ' . groups + endif - " 'dir', swap file in directory relative to the current dir - set dir=Xtest.je,~ + 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)) - call mkdir("Xtest.je") - call writefile(content, 'Xtest2/Xtest3') - edit Xtest2/Xtest3 - call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1)) - let swfname = "Xtest.je/Xtest3.swp" - call assert_equal(swfname, split(execute("swapname"))[0]) - call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1)) + bwipe! + endif + endif - set dir& - call delete("Xtest1") - call delete("Xtest2", "rf") - call delete("Xtest.je", "rf") + call delete('Xtest') endfunc diff --git a/src/version.c b/src/version.c index b7cb58be4..2a2cefe3d 100644 --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1263, +/**/ 1262, /**/ 1261, |