Why can I modify a read-only file?

24,000

Solution 1

As @Rob already mentioned, you can only do this if you have write access to the directory containing the file. Attempting to do the same thing to a file in, for example, /etc will fail.

As for how vim is doing this, it deletes the file and recreates it. To test this, I created a file owned by root:

echo foo | sudo tee fff

And then proceeded to edit the file with vim in the way that you describe, but attaching the process to strace to see what's happening:

strace vim fff 2> strace.out

I then checked strace.out and found:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

So, the file was first deleted (unlink("fff")), then a new file of the same name was created (open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) and the modifications I had made were written to it (write(4, "foasdasdao\n", 11)). If you try this at home, you will see that after you edit it with vim, the file will now belong to you and not root.

So, strictly speaking, vim isn't editing a file you have no write access to. It is deleting a file from a directory to which you do have write access and then creating a new file to which, again, you have write access.

Solution 2

As long as you own the parent directory you can remove, or replace a file no matter the permission since you can change the content of the directory :).

Try it with other command like rm, it will prompt you but you can still do it. Make the directory not writable and that should stop it.

Addition:

Just tried it but as long as I own the file I can still modify it, even with the folder read only. However when I change ownership to root:root it cannot open the file for write. So solves the modifying files owned by root (or someone else)

Solution 3

Using w! you are removing the original file (which you are permitted to do) and writing your version instead.

When you have write access to a directory, you can: create, move or delete files within that directory.

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

Now let me switch my user and change the file

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

Now see what is in there:

$ cat foo/file
bye

Solution 4

See :help write-readonly:

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

Since you have write permissions on the directory (meaning you can create, delete, or rename files in it), the system does allow it.


The default value of cpoptions does not contain W:

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

Solution 5

Both your vim editor process and your file carry your

 getpwnam("navid")->pw_uid

ownership so that you could also shell out

 :!chmod +w %

and you might guess that once upon a time the even simpler

 :!rm %

(requiring only +w,u-t unlink permission on . and not even ownership) became too frequent for someone to type so that vim was reprogrammed to automatically offer and upon request automagically perform such an operation.

Try overwriting your big sister's

 /home/whoopi/.profile

as mere navid and bets are your vim gives you your desired refusal.

Share:
24,000

Related videos on Youtube

Positive Navid
Author by

Positive Navid

I work at the Microsoft Azure Machine Learning team.

Updated on September 18, 2022

Comments

  • Positive Navid
    Positive Navid over 1 year

    Short Question:

    Why can we manipulate a read-only file in Vim using : + w + q + ! even without being an administrator?

    Long Question:

    I have a text file (myFile.txt) which is read-only for everyone:

    navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
    -r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt
    

    I can open it with Vim without having admin privileges:

    navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 
    

    I modify it and press: Esc + : + w + q + Enter and I see this error message:

    E45: 'readonly' option is set (add ! to override)
    

    So far, everything makes sense. But when I press: Esc + : + w + q + ! + Enter, Vim saves the changes.

    I'm using Ubuntu 16.04 and VIM 7.4.

    • Rob
      Rob over 7 years
      @Zanna Do you own the directory that the file is in?
    • Rob
      Rob over 7 years
      Yeah this would be a HUGE problem otherwise :)
    • David Schwartz
      David Schwartz over 7 years
      Modifying a file and replacing a file are two different things with different permission requirements.
    • Panagiotis Tabakis
      Panagiotis Tabakis over 7 years
      You might want to have a look at this. It basically answers your question and as @DavidSchwartz correctly pointed out: Modifying a file and replacing a file are two different things
    • Rob
      Rob over 7 years
      @PanagiotisTabakis Very nice find this is brilliant.. chmod to make the file read-write and back again if you own it.. LOVE IT :)
    • Lupen
      Lupen over 7 years
    • goo
      goo over 7 years
      Vim feature. ! tries to chmod the file to save your edits.
    • goo
      goo over 7 years
      And ! will not override a read-only filesystem or device.
  • CCJ
    CCJ over 7 years
    deleting a file is not considered a write operation? That seems unintuitive
  • terdon
    terdon over 7 years
    @CCJ it's a write operation on the directory but not the file, no. Write operations on files are those that change the file's contents. By the same token, creating/deleting files are write operations on the directory since you're changing its contents.
  • Peter Cordes
    Peter Cordes over 7 years
    strace has a -o strace.out option, so you can leave the stderr of the traced process connected to the tty. You could also use -efile,write to trace only filesystem and write calls, not mmap / signals / anything else.
  • Peter Cordes
    Peter Cordes over 7 years
    Also, that's a dangerous order of operations. It would be safer to write the replacement to a new filename and then use rename(2) to replace the old file. Then there's no time window where your data doesn't exist on disk.
  • Peter Cordes
    Peter Cordes over 7 years
    It sounds like VIM chooses from multiple strategies, including rewrite-in-place or unlink+write a new file.
  • terdon
    terdon over 7 years
    @PeterCordes um, OK. You might want to direct your complaints to the vim developers though. I don't even use the thing, I'm in the emacs camp.
  • Peter Cordes
    Peter Cordes over 7 years
    I'm also an emacs user >.< Oh well, I guess it works well enough for most people.
  • Rob
    Rob over 7 years
    @PeterCordes Yes It apparently will try very hard to do what you tell it to :) very crafty. :)
  • Dolchio
    Dolchio over 7 years
    @CCJ: Just like how you can delete a const object in most programming languages.
  • StarWeaver
    StarWeaver over 7 years
    @PeterCordes Vim does almost always have a .swp file on disk already to protect your data; be interesting to see if forcing that off changes the order of operations.
  • andyg0808
    andyg0808 over 7 years
    @PeterCordes I believe Vim allows the method used to modify a file to be changed. See vimdoc.sourceforge.net/htmldoc/editing.html#backup and particularly vimdoc.sourceforge.net/htmldoc/options.html#%27backupcopy%27‌​. Is that something like what you were thinking of?
  • Peter Cordes
    Peter Cordes over 7 years
    @andyg0808: yes. That makes sense, I thought VIM would have lots of options to control how it handled replacing files, since that's definitely something that people want their editor to get right (for their own personal definition of right).
  • njzk2
    njzk2 over 7 years
    so basically, write permission on a file is only useful if you don't have the write permission on the directory
  • fkraiem
    fkraiem over 7 years
    @CCJ Deleting a file is a write operation to the directory containing it, not to the file itself. It is perfectly intuitive that if you are in charge of a directory (i.e., have write access to it), you should be able to control what's in it, and the owner of an individual file should not be allowed to override you.
  • terdon
    terdon over 7 years
    @njzk2 well, no. If you don't have write access to the file, you can't write to it. You must delete it and create a new file with the same name. That's a very different thing. For instance, it changes the permissions and ownership of the file.
  • njzk2
    njzk2 over 7 years
    @terdon I wouldn't go as far as call that very different. The result is similar: there is a file with the same name, and it has my content in it.
  • DeadMG
    DeadMG over 7 years
    This answer sounds to me like "The permissions model is broken". You say the file is read-only, it's just that I can change the contents arbitrarily.
  • til_b
    til_b over 7 years
    The permissions model is fully fine, you just have to set correct permissions for the parent directory.
  • terdon
    terdon over 7 years
    @DeadMG The permission model is fine, you just misunderstand how it works. If you have write access to a directory, that means you have full access to create and delete files in that directory. This is normal and is the case in all permission systems. You can, therefore, delete and recreate a file. You can't modify the file though. If you want to make a file read-only, you don't put it in a directory that can be written to. Calling that system broken is like complaining that someone opened your safe when you gave them the keys to it.
  • Roman Czyborra
    Roman Czyborra over 6 years
    Thank you @Zanna for the code editing even though it cost me novice a tiny bit of reputation, deservedly though.