6

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?

4
  • 3
    so I think that chmod 0300 would give d-wx------ which would allow you to cd into the directory (due to x), but not list the files (no r). However because you didn't set the permissions recursively (chmod -R 0300 fooledYa/) the child directory ohReally has normal drwx------ permissions, hence as you see.
    – Tom
    May 31, 2012 at 1:09
  • @TomH That's how I rationalized it as well. At first glance, however, it appears that there are two permissions for the same inode info. One from fooledYa with read permissions revoked on all files/directories, and one from ohReally with read permissions granted on all files/directories INCLUDING . which points to itself.
    – puk
    May 31, 2012 at 1:13
  • 2
    I think the example would have to be more explicit, I don't see that as conflicting. Basically chmod 0300 somedir revokes the permission to read the somedir listing, and not anything to the contents.
    – Tom
    May 31, 2012 at 1:20
  • I have used directory permissions like 0710 and 0711 for things that need to be visible to e.g. daemons but shouldn't be too easy for a casual user to get into. It isn't bullet-proof security, but for non-owner, non-root users, makes it just a little harder to look at the contents of the directory while still allowing access based on a full file path.
    – user
    May 31, 2012 at 8:41

3 Answers 3

14
$ 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

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.

1

I believe the specific thing that is fooling you is that every directory below / has at least two links to it: the directory's entry in its parent and . within itself (plus any .. links from child directories). When you type ls -ld . it's looking at the . link in the current directory (which you have permission to read), not the link to the current directory from the parent directory (which you don't have permission to read).

For +x, I've found the easiest way to understand how it works on directories is permission to "get into" the directory. You can't get into a directory without +x at all, even if you have read and write access to it. If you aren't allowed into a directory, you can't get into the subdirectories whether they have +x set or not. So, if you have fooledYa/ohReally/foo.txt and fooledYa is is chmod 0000, assuming no other ACL system overrides the file mode, only root would be able to get into ohReally/ or open foo.txt even if they know the path to the file without having to list the directory contents.

One of the odd things about these permissions is that if the directory is +r but not +x, you have permissionto read the directory contents so you can "peek in" from outside and read the list of files in the directory, but without +x you won't be able to get into the directory to access (stat) the individual files. Therefore if you try to ls -l such a directory you'll get filenames but all the other fields for filesizes, modes, ownership, etc will be ? marks.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .