mirror of
https://github.com/neovim/neovim.git
synced 2026-08-26 09:01:57 +00:00
vim-patch:9.2.1005: backupcopy=auto overwrites a file in place with umask (#41502)
Problem: backupcopy=auto overwrites a file in place when umask is restrictive.
The probe treats permission restore as impossible and writes in
place, keeping the same inode.
Solution: When creating the probe file, open() applies umask, so a 0644
file becomes 0600 with umask 0077. Use fchmod() to fix the
permissions of the probe (Pranav Dwivedi).
closes: vim/vim#21137
fd8aea135d
Co-authored-by: Pranav Dwivedi <dwivedipranav2021@gmail.com>
This commit is contained in:
@@ -743,7 +743,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
|
||||
|| !os_fileinfo_id_equal(&file_info, file_info_old)) {
|
||||
*backup_copyp = true;
|
||||
} else {
|
||||
// Check if we can create a file and set the owner/group to
|
||||
// Check if we can create a file and set the owner/group/mode to
|
||||
// the ones from the original file.
|
||||
// First find a file name that doesn't exist yet (use some
|
||||
// arbitrary numbers).
|
||||
@@ -764,6 +764,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
|
||||
} else {
|
||||
#ifdef UNIX
|
||||
os_fchown(fd, (uv_uid_t)file_info_old->stat.st_uid, (uv_gid_t)file_info_old->stat.st_gid);
|
||||
os_fsetperm(fd, perm);
|
||||
if (!os_fileinfo(tmp_fname, &file_info)
|
||||
|| file_info.stat.st_uid != file_info_old->stat.st_uid
|
||||
|| file_info.stat.st_gid != file_info_old->stat.st_gid
|
||||
|
||||
@@ -804,6 +804,16 @@ int os_setperm(const char *const name, int perm)
|
||||
return (r == kLibuvSuccess ? OK : FAIL);
|
||||
}
|
||||
|
||||
/// Set the permission of the file referred to by the open file descriptor.
|
||||
///
|
||||
/// @return `OK` for success, `FAIL` for failure.
|
||||
int os_fsetperm(int fd, int perm)
|
||||
{
|
||||
int r;
|
||||
RUN_UV_FS_FUNC(r, uv_fs_fchmod, fd, perm, NULL);
|
||||
return (r == kLibuvSuccess ? OK : FAIL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XATTR
|
||||
/// Copy extended attributes from_file to to_file
|
||||
void os_copy_xattr(const char *from_file, const char *to_file)
|
||||
|
||||
@@ -1013,4 +1013,24 @@ func Test_write_with_xattr_support()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_backupcopy_auto_restrictive_umask()
|
||||
CheckUnix
|
||||
call writefile(['FOO'], 'Xumaskfile', 'D')
|
||||
call setfperm('Xumaskfile', 'rw-r--r--')
|
||||
let inode_before = systemlist('ls -i Xumaskfile')[0]->matchstr('^\s*\zs\d\+')
|
||||
call writefile([
|
||||
\ 'set backupcopy=auto writebackup nobackup backupskip=',
|
||||
\ 'edit Xumaskfile',
|
||||
\ 'call setline(1, ["BAR"])',
|
||||
\ 'write',
|
||||
\ 'qall!'
|
||||
\ ], 'Xumaskscript', 'D')
|
||||
call system('umask 0077; ' .. GetVimCommand() .. ' -i NONE -n -S Xumaskscript')
|
||||
call assert_equal(0, v:shell_error)
|
||||
call assert_equal(['BAR'], readfile('Xumaskfile'))
|
||||
call assert_equal('rw-r--r--', getfperm('Xumaskfile'))
|
||||
call assert_notequal(inode_before,
|
||||
\ systemlist('ls -i Xumaskfile')[0]->matchstr('^\s*\zs\d\+'))
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
Reference in New Issue
Block a user