Unix file permissions fall into three basic categories, read, write and execute. Which one do you think controls file deletion? It’s probably write, right? Well, let’s test it:
$ touch foo; chmod -w foo
$ ls -l foo
-r-------- 1 user group 0 2011-01-24 12:16 foo
$ rm foo
$ ls foo
ls: cannot access foo: No such file or directory
That’s weird, it looks like I successfully deleted that file. Maybe it’s governed by user/group ownership.
$ touch foo; sudo chown root:root foo
$ ls -l foo
-rw------- 1 root root 0 2011-01-24 12:18 foo
$ rm foo
$ ls foo
ls: cannot access foo: No such file or directory
I just deleted a file owned by root. WTF?
It turns out, Unix file deletion (and creation) is controlled by write access to the parent directory. Let’s demonstrate quickly:
$ mkdir test; touch test/foo
$ chmod -w test
$ rm test/foo
rm: test/foo: Permission denied
You see, each Unix file has a dedicated datastructure that stores metadata called an inode. While inodes store permissions, access/modification timestamps and other useful info, they do not track file location or name. Instead, directories map file names to inodes. The name of an inode is derived from its location. When we delete a file with the rm command, we are merely removing a directory entry. Hence, we only need write permissions to the directory in question.
You can even link to an inode from multiple directory locations with the ln command. These references are called hard links and are counted by the inode. The inode is reclaimed and the disk storage freed only when the reference count reaches zero. So not all rm operations will result in the underlying file being destroyed, which is yet another reason for file deletion being controlled by the parent directory.
-
paksoy posted this