diff options
Diffstat (limited to 'src')
| -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' | 
