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.
5a73e0ca54
This commit is contained in:
Jan Edmund Lazo 2019-04-29 19:58:53 -04:00
parent 63526f2eee
commit 0cecf9f121
2 changed files with 54 additions and 3 deletions

View File

@ -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
}

View File

@ -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'