Hacking Linux Exposed





previous article
next article
Linux File Permission Confusion pt 2
By Bri Hatch.

Summary: File permissions, the most basic form of security control that exists on Unix-like systems, is still misunderstood by many.

Before I start, I really suggest anyone interested in Linux who is near the US Pacific Northwest, check out and attend Linuxfest Northwest this Saturday. We've got gurus, raffles, and swag galore, and the whole event is free. I'll be giving a Linux Security presentation that promises to cover all Linux Security hooks in one hour or less, so it'll be a wild ride. See http://linuxnorthwest.org/ for more information.

Last week I gave a much-needed refresher on how file permissions actually work, as opposed to how many people think they work. Just to be complete, this week I'll discuss how file permissions on directories work, which operate slightly differently.

Read (r)
The ability to read the names of files stored in this directory.

Write (w)
The ability to rename files in the directory, create new files, or delete existing files, if you also have Execute permissions. If you don't have execute perms, then write perms are meaningless.

Execute (x)
The ability to cd into this directory, and access the files in this directory.

How a directory functions is one of the most frequently misunderstood file permission issues. Here are a few examples that should make it easier to understand.

 # "Full Access".  Reegen can list, create, delete, rename, delete,
 # and stat any files in dir.
 # Access to file contents is subject to the permissions
 # of the file itself.
 # New files can be created, any file can be deleted, regardless of
 # file permissions.
 drwx------  1 reegen    reegen          4096 Jan 01 2003  dir

 # Reegen can do everything in the "Full Access" list except create,
 # delete, or rename files in this directory.
 dr-x------  1 reegen    reegen          4096 Jan 01 2003  dir

 # Reegen can do everything in the "Full Access" list except list the
 # filenames in this directory.  If she suspects there is a file
 # named "program" she can list it, but cannot do an 'ls'
 # of the directory itself.  She can access any file (file
 # permissions permitting) if she knows it's name.  She can
 # create new files, or rename/delete existing ones.
 d-wx------  1 reegen    reegen          4096 Jan 01 2003  dir

 # Reegen cannot create or delete any files in this directory.
 # She can access any file (permissions permitting) if she
 # knows it's name already.
 d--x------  1 reegen    reegen          4096 Jan 01 2003  dir

Over the years I have explained the meaning of r, w, and x on directories countless times. Many people don't realize that write access means the ability to create or delete files, and that the permissions of the file itself is totally irrelevant. This does make sense if you think about it. When you add files, what are you doing? You're putting a new entry into the directory listing - it is the directory that is changing, so that's why you need write permission to the directory. It's the same situation with deleting - the directory (list of files) is being changed, so if you have write access, you can do so regardless of the permissions of the file itself.[1]

So what do you do when you need to allow write permissions on a directory for a group of people, but don't want to let them delete each other's files? That's the purpose of the "sticky" bit, "t" which you can apply to a directory[2]. When this bit is set, a user can only delete files if they are the owner. This is most common in directories like /tmp:

  $ cd /tmp
  $ ls -ld /tmp
  drwxrwxrwt    4 root     root         4096 Jan 22 16:43 /tmp
  $ whoami
  $ ls -l
  -rw-rw-rw-    1 reegen   reegen     164864 Dec  6 13:53 a.gif
  -rw-rw-rw-    1 anurup   anurup      98302 Oct 13 14:06 a.pdf
  -rw-rw-rw-    1 reegen   reegen       5857 Jan 21 13:57 a.txt
  $ rm a.pdf; ls -l
  -rw-rw-rw-    1 reegen   reegen     164864 Dec  6 13:53 a.gif
  -rw-rw-rw-    1 reegen   reegen       5857 Jan 21 13:57 a.txt
  $ rm a.txt; ls -l
  rm: cannot unlink `a.txt': Operation not permitted
  -rw-rw-rw-    1 reegen   reegen     164864 Dec  6 13:53 a.gif
  -rw-rw-rw-    1 reegen   reegen       5857 Jan 21 13:57 a.txt

Note that even though he has write permissions to /tmp anurup can't delete any files but his own - he's prevented by the sticky bit.

There's one last strange bit you can apply to a directory, the set group id bit. If you set the sgid bit on a directory, any files created in that directory will have their group ownership set to the directory's group owner:

  $ cd /tmp

  $ id
  uid=1000(anurup) gid=1000(anurup) groups=1000(anurup)

  $ touch normalfile; ls -lda . normalfile
  drwxrwxrwt    2 root     root         4096 Dec  6 18:27 .
  -rw-------    1 anurup   anurup       5857 Jan 21 13:57 normalfile

  $ cd /path/to/some/sgid_directory; ls -ld .
  drwxrwsrwt    2 root     fuzzies      4096 Oct 13  9:52 .

  # Note the 's' in group's execute field above.

  $ touch normalfile; ls -l normalfile
  -rw-------    1 anurup   fuzzies      5857 Jan 21 13:57 normalfile

As you can see, when a file was created in the sgid_directory the group was set to 'fuzzies' automatically. The user doesn't even need to be a member of this group at all.

This feature is frequently used to ease administration. If you have a directory where the files must be readable by a specific group, users would normally need to be part of this group and run the chgrp command, or leave the files world readable. If the directory forces new files to be part of this group, you need only set your umask correctly (for example umask 027 or umask u=rwx,g=rx,o=) and don't need to manually fix permissions ever.

In response to my column last week, Antonomasia took issue with the section where we created files that were accessible to everyone except for those in the specific group:

  -rwx---r-x    1 root     jerks       74088 Sep 23 15:13 /usr/bin/gcc

I said that creating this set of permissions would allow you to create a group called 'jerks' and put troublesome users in it, thus denying them access to gcc.

This works on Linux just fine, because in Linux normal users cannot change the groups to which they are a member[3]. However in many other Unix-like operating systems, a user can drop groups from the supplemental groups list at will. On these systems, a savvy miscreant could drop his 'jerks' group and again have access to gcc[4].

This has been a public service announcement to correct common file permission misconceptions. Next week we return you to your regularly scheduled security column.


[1] Some versions of rm will complain if you try to remove an unwritable file - this is a handy feature of rm, not the Linux kernel. Try deleting your file with the actual kernel unlink() system call (e.g. perl -e 'unlink "filename"') and you'll see the kernel is not so demanding.

[2] Ten brownie points to the first person who can tell me why it was originally named the sticky bit.

[3] Specifically, in Linux only root can use the setgroups(2) system call. Or, to be most accurate, any user with the CAP_SETGID capability.

[4] Of course, in the case of programs, there's no reason someone couldn't upload a copy of their software from home using scp/sftp/ftp or other hacks. You can, at best, restrict them to writing only to directories that are mounted without exec permissions.

However if you're trying to protect access to files in "allow-everyone-but-this-group" directories, then this method works superbly on Linux -- but it can be circumvented on many other Unix-like OSs.

Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. Several years ago he ran 'chown bree /dev/heart' and has been happy ever since. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2003

This is the April 24, 2003 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com.

previous article
next article