Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-122841

vim writes file in place even though creating a backup is possible

Linking RHIVOS CVEs to...Migration: Automation ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Undefined Undefined
    • None
    • rhel-9.6
    • vim
    • None
    • None
    • Low
    • 1
    • rhel-stacks-web-servers
    • 0
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • _WS-Refined_
    • None
    • None
    • Unspecified
    • Unspecified
    • Unspecified
    • None

      What were you trying to do that didn't work?

      When editing a file, we can expect that whenever possible a backup is made and a new inode for the file is being created, and this is what we observe most of the time.
      However, when umask is set to 0077, no such backup is created and file is modified in-place.
      This is problematic when bash is currently executing a long-running script and that script is being modified using vim: bash then executes the modified version of the script (because it has same inode) causing potential breakage.

      The reason for not writing a backup is because the test on file creation is considered as failing:

      1203                 // Check if we can create a file and set the owner/group to
      1204                 // the ones from the original file.
      1205                 // First find a file name that doesn't exist yet (use some
      1206                 // arbitrary numbers).
      1207                 STRCPY(IObuff, fname);
      1208                 for (i = 4913; ; i += 123)
      1209                 {
      1210                     sprintf((char *)gettail(IObuff), "%d", i);
      1211                     if (mch_lstat((char *)IObuff, &st) < 0)
      1212                         break;
      1213                 }
      1214                 fd = mch_open((char *)IObuff,
      1215                                     O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
       :
      1224                     if (mch_stat((char *)IObuff, &st) < 0
      1225                             || st.st_uid != st_old.st_uid
      1226                             || st.st_gid != st_old.st_gid
      1227                             || (long)st.st_mode != perm)
      1228                         backup_copy = TRUE;
      

      Here above when umask is set to 0077, creating the test file "4913" with "0100644" creates the file with 0600 permissions due to the mask:

      5642  09:08:29.728637 newfstatat(AT_FDCWD</home/user>, "4913", 0x7ffdce200970, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory) <0.000043>
      5642  09:08:29.728797 openat(AT_FDCWD</home/user>, "4913", O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW, 0100644) = 3</home/user/4913> <0.000217>
      5642  09:08:29.729123 fchown(3</home/user/4913>, 1000, 1000) = 0 <0.000056>
      5642  09:08:29.729252 newfstatat(AT_FDCWD</home/user>, "4913", {st_dev=makedev(0xfc, 0x10), st_ino=141, st_mode=S_IFREG|0600, st_nlink=1, st_uid=1000, st_gid=1000, ...}, 0) = 0 <0.000048>
      5642  09:08:29.729413 close(3</home/user/4913>) = 0 <0.000051>
      5642  09:08:29.729526 unlink("4913")    = 0 <0.000087>
      

      Due to this, writing the target file is done in-place:

      5642  09:08:29.748784 openat(AT_FDCWD</home/user>, "test", O_WRONLY|O_CREAT, 0644) = 3</home/user/test> <0.000265>
       :
      5642  09:08:29.749590 ftruncate(3</home/user/test>, 0) = 0 <0.000212>
      5642  09:08:29.749912 write(3</home/user/test>, "FOO\n", 4) = 4 <0.000082>
      5642  09:08:29.750074 fsync(3</home/user/test>) = 0 <0.005712>
      5642  09:08:29.756110 fchmod(3</home/user/test>, 0100644) = 0 <0.000196>
      5642  09:08:29.756477 close(3</home/user/test>) = 0 <0.000054>
      

      IMHO after creating the test file "4913", it should try doing a "fchmod", if it succeeds, then the backup when creating "test" should be done.

      What is the impact of this issue to you?

      bash doesn't execute original script but currently modified one.

      Please provide the package NVR for which the bug is seen:

      vim-enhanced-8.2.2637-22.el9_6

      How reproducible is this bug?

      Always

      Steps to reproduce

      1. Change umask
        $ umask 0077
      2. Check inode of file to be edited
        $ stat test -c %i
        143
      3. Edit file and save it
        $ vim test
        :wq
        
      4. Check inode again
        $ stat test -c %i

      Expected results

      A different inode number

      Actual results

      Same inode number

              zdohnal@redhat.com Zdenek Dohnal
              rhn-support-rmetrich Renaud Métrich
              Zdenek Dohnal Zdenek Dohnal
              Frantisek Hrdina Frantisek Hrdina
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated: