Can Linux file permissions be fooled?

I came across this example today and I wondered how reliable Linux file permissions are for hiding information

$ mkdir fooledYa
$ mkdir fooledYa/ohReally
$ chmod 0300 fooledYa/
$ cd fooledYa/
$ ls 
>>> ls: cannot open directory .: Permission denied
$ cd ohReally
$ ls -ld .
>>> drwxrwxr-x 2 user user 4096 2012-05-30 17:42 .

Now I am not a Linux OS expert, so I have no doubt that someone out there will explain to me that this is perfectly logical from the OS's point of view. However, my question still stands, is it possible to fool, not hack, the OS into letting you view files/inode info which you are not supposed to? What if I had issued the command chmod 0000 fooledYa, could an experienced programmer find some round about way to read a file such as fooledYa/ohReally/foo.txt?


Solution 1:

$ ls -lhd fooledYa/
d-wx------ #snip

First thing's first: I can write to the directory (make new entries) and I can execute (cd) to the directory. I can't read the directory, though. What that means isn't intuitive.

When you work with directories in Unix systems, the directory point to inodes, which are different things than the pointer entry. Being able to follow references down a directory tree is controlled by the eXecute bit. For each directory level down the tree, the operating system checks the execute bit before descending to the next level.

Meanwhile, the Read bit controls accessing the inode's contents. Everything you can reference on your filesystem is an inode entry. Directories or files, they point to an inode.

ls -ldi fooledYa/
121100226 d-wx------ #snip

In this case, the directory inode is 121100226. The read permission tells whether I can access that inode file in userspace to read its contents. The contents of the directory inode are the references to other files. The kernel can always read that. You as a user are controlled by the kernel's decisions regarding the entries within that.

Thus, since ls tries to read the contents to tell me what's there (as checked by the Read flag), it is denied. Since I still have eXecute permission, however, the kernel will allow me to traverse to files that I specify if the directories above the file I want all permit me to eXecute into them, regardless of whether I can read them to see what the reference.

So, to summarize for directories, think of execute as a master permission. Without it, you can't enter the directory to do anything. After that, think of them as a two column file. If you have read permission, you can see the entries. If you have write permission, you can add or remove entries. If you lack those two permissions but have execute, you can make references to entries in the list, but you cannot read the list.

This is a good illustrative examples of inodes and how they represent directory references and file block on disk references: http://teaching.idallen.com/dat2330/04f/notes/links_and_inodes.html

Solution 2:

As you anticipated, plenty of people have explained how your example is perfectly logical. "Works as designed."

To answer your question, it would be an egregious kernel bug if you were able to fool the OS into letting you view files/inode info which you are not supposed to. The file permissions are associated with the inode itself and are applied when you actually try to open the file. In case you didn't pick it up from the other answers, I'll point out that a directory has an inode like any file does, it's just that the permissions mean something slightly (or greatly) different when applied to directories.

File permissions are the original Unix security mechanism and are still an integral part of Unix/Linux security. Any scenario you can cook up that looks like you have fooled the system is almost certainly a case of you not understanding what the correct behavior is. If you found a legitimate way to bypass security, even in hacks, it would be considered a critical security bug and would be among the highest priorities to patch.

For example, if you were able to read the contents of a file you were not supposed to be able to read, you could steal the (hashed) passwords of all the users and the private ssh key for the system and the private ssh keys of everyone on the system (though hopefully those would be encrypted) and via a device inode read the entire contents of system memory (and much more). It would be less dangerous if you could read file info you were not supposed to, but it would still be considered a major breach.