Skip to main content
edited body
Source Link
Stéphane Chazelas
  • 586.3k
  • 96
  • 1.1k
  • 1.7k

This is happening because of two things:

  • vim (at least in this case) and sed, when doing in place editing, actually delete the original file and then create a new one with the same name.

  • the ability to delete a file depends on the permissions of the directory containing the file, not on the permissions of the file itself.

So, what is happening here is that you have write permission on the directory, which means you can change the directory's contents, including deleting and creating files. So when you run your sed -i or save with :w!, you are deleting the original and then creating a new file. This is also why the ownership changes: this is actually a different file.

You can demonstrate this by checking the file's inode before and after editing:

$ ls -ld foo/ drwxr-xr-x 2 terdon terdon 266240 Nov 16 13:43 foo/ $ cd foo $ sudo sh -c 'echo foo > file' $ ls -l total 4 -rw-r--r-- 1 root root 4 Nov 16 13:4243 file 

After those commands, I have file, owned by root, in the directory foo/ to which my regular user has write permission. Now, let's use ls -i to check the inode, and then make a changed with sed and check again:

$ ls -li file 26610890 -rw-r--r-- 1 root root 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 

You can also see vim doing the same thing by running

strace vim file 2> strace.out 

Then editing the file and saving with :w!. In your strace.out, you will see:

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

So, the file was first deleted (unlink("file")), then a new file of the same name was created (open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)) and the modifications I had made were written to it (write(4, "bar\n", 11)).

As you can see above, the inode changed: this is a new file with the same name. So you did not actually change a file you didn't have write access to, you changed a directory to which you did have write access by deleting a file in that directory and then creating a new file in the directory with the same name as the old one.

I have answered a similar question here: https://askubuntu.com/a/815849/85695.

This is happening because of two things:

  • vim (at least in this case) and sed, when doing in place editing, actually delete the original file and then create a new one with the same name.

  • the ability to delete a file depends on the permissions of the directory containing the file, not on the permissions of the file itself.

So, what is happening here is that you have write permission on the directory, which means you can change the directory's contents, including deleting and creating files. So when you run your sed -i or save with :w!, you are deleting the original and then creating a new file. This is also why the ownership changes: this is actually a different file.

You can demonstrate this by checking the file's inode before and after editing:

$ ls -ld foo/ drwxr-xr-x 2 terdon terdon 266240 Nov 16 13:43 foo/ $ cd foo $ sudo sh -c 'echo foo > file' $ ls -l total 4 -rw-r--r-- 1 root root 4 Nov 16 13:42 file 

After those commands, I have file, owned by root, in the directory foo/ to which my regular user has write permission. Now, let's use ls -i to check the inode, and then make a changed with sed and check again:

$ ls -li file 26610890 -rw-r--r-- 1 root root 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 

You can also see vim doing the same thing by running

strace vim file 2> strace.out 

Then editing the file and saving with :w!. In your strace.out, you will see:

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

So, the file was first deleted (unlink("file")), then a new file of the same name was created (open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)) and the modifications I had made were written to it (write(4, "bar\n", 11)).

As you can see above, the inode changed: this is a new file with the same name. So you did not actually change a file you didn't have write access to, you changed a directory to which you did have write access by deleting a file in that directory and then creating a new file in the directory with the same name as the old one.

I have answered a similar question here: https://askubuntu.com/a/815849/85695.

This is happening because of two things:

  • vim (at least in this case) and sed, when doing in place editing, actually delete the original file and then create a new one with the same name.

  • the ability to delete a file depends on the permissions of the directory containing the file, not on the permissions of the file itself.

So, what is happening here is that you have write permission on the directory, which means you can change the directory's contents, including deleting and creating files. So when you run your sed -i or save with :w!, you are deleting the original and then creating a new file. This is also why the ownership changes: this is actually a different file.

You can demonstrate this by checking the file's inode before and after editing:

$ ls -ld foo/ drwxr-xr-x 2 terdon terdon 266240 Nov 16 13:43 foo/ $ cd foo $ sudo sh -c 'echo foo > file' $ ls -l total 4 -rw-r--r-- 1 root root 4 Nov 16 13:43 file 

After those commands, I have file, owned by root, in the directory foo/ to which my regular user has write permission. Now, let's use ls -i to check the inode, and then make a changed with sed and check again:

$ ls -li file 26610890 -rw-r--r-- 1 root root 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 

You can also see vim doing the same thing by running

strace vim file 2> strace.out 

Then editing the file and saving with :w!. In your strace.out, you will see:

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

So, the file was first deleted (unlink("file")), then a new file of the same name was created (open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)) and the modifications I had made were written to it (write(4, "bar\n", 11)).

As you can see above, the inode changed: this is a new file with the same name. So you did not actually change a file you didn't have write access to, you changed a directory to which you did have write access by deleting a file in that directory and then creating a new file in the directory with the same name as the old one.

I have answered a similar question here: https://askubuntu.com/a/815849/85695.

corrected the first "ls -li" in the 2nd block: file is root:root initially.
Source Link
Olivier Dulac
  • 6.6k
  • 1
  • 26
  • 42
$ ls -li file 26610890 -rw-r--r-- 1 terdonroot terdonroot 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 
$ ls -li file 26610890 -rw-r--r-- 1 terdon terdon 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 
$ ls -li file 26610890 -rw-r--r-- 1 root root 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 
added 89 characters in body
Source Link
terdon
  • 252.7k
  • 69
  • 481
  • 719
$ ls -lli file  2661089126610890 -rw-r--r-- 1 terdon terdon 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ $ ls -ili file 2661089026610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 
$ ls -l file 26610891 file $ sed -i 's/foo/bar/' file $ ls -i file 26610890 file 
$ ls -li file  26610890 -rw-r--r-- 1 terdon terdon 4 Nov 16 13:43 file $ sed -i 's/foo/bar/' file $ $ ls -li file 26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file 
added 24 characters in body
Source Link
terdon
  • 252.7k
  • 69
  • 481
  • 719
Loading
Source Link
terdon
  • 252.7k
  • 69
  • 481
  • 719
Loading