About | ACP | Get Stuff | Industry Watch | Learning Curve | Newsletter | Search | Test Drive
Home » Learning Curve » ACP Guru

More File Stuff

All the wonderful things you can do to a bunch of your poor innocent files.

Get It

Try It

Two previous articles (here and here) discussed Unix file permissions, file ownership, and how this applies to both files and directories. They also mentioned that Unix file permissions customarily use an octal radix. The term mode was also introduced and used interchangeably with permissions.

But file modes and file permissions aren't the same thing. And there are three more octal digits used to describe Unix file system objects beyond the three permissions digits.

Permissions, Modes, Types

A file mode is more than the file's permissions. Three digits are used to describe a file's permissions (for user, group, other) but there are three additional octal digits in a file mode.

The leftmost two of these describe a file type and the third adds three bits to further govern behaviour.

A Unix 'file type' is not something like 'TextEdit document' - it's a distinct object type unrelated to applications used in the system. Descriptions such as 'TextEdit document' are generated by the Cocoa application configuration file Info.plist found in the application bundle in the subdirectory Contents. These names are associated with file extensions and UTIs (uniform type identifiers). They're not the same thing as Unix file types.

Unix has eight distinct file types.

Named Pipe/FIFO Buffer010000These are communication channels. You won't see too many of these.
Character Device020000You'll find these in your /dev directory. They communicate in byte streams.
Directory040000Exactly what it sounds like.
Block Device060000You'll find these in your /dev directory as well. They communicate in blocks of I/O all at once.
Regular100000Ordinary files. Yes, the kind you normally read and save on disk.
Symbolic Link120000They contain one thing and one thing only: a path to another file. They're often called 'symlinks' for short.
Socket140000A basic communication channel. The entire Internet is built on the concept.
Whiteout160000A file system object that hides another object, perhaps through a mount point.

Although Finder and Apple's 'save as' dialogs don't care much about Unix file types, Xfile does. You're not permitted to overwrite an object of one type with an object of another type. Why not? Because such operations can be disastrous, because one would rarely if ever entertain such an idea, and because computer 'mechanical failure' (clicking a push button by mistake, hitting enter by mistake) is too prevalent and just too easy. (For this reason you will always have to pass through at least one 'are you sure' Xfile prompt to remove anything - on Unix, deleted things never come back.)

A file's type never changes. It's immutable. If you want a new file of a different type but with the same name at the same path then you need to remove the first one before creating the second.

The Third Digit

The next digit over (from the left) governs additional behaviour on the part of the file or directory. This digit can contain up to three bit-wise values. The value 1 denotes the sticky bit, the value 2 the set GID bit, and the value 4 the set UID bit.

Sticky bits were initially used to tell the OS kernel when binary images shouldn't be swapped out to disk. Thereof the name: these executables were to stick in memory because they were used so often. That convention passed with the introduction of better virtual memory systems but the bit remains and today it's used to guard directories instead. As the system's man pages clarify:


A special file mode called the sticky bit is used to indicate special treatment for shareable executable files and directories.


The sticky bit has no effect on executable files. All optimization on whether text images remain resident in memory is handled by the kernel's virtual memory system.


A directory whose 'sticky bit' is set becomes an append-only directory, or more accurately a directory in which the deletion of files is restricted. A file in a sticky directory may only be removed or renamed by a user if the user has write permission for the directory and the user is the owner of the file, the owner of the directory, or the superuser. This feature is usefully applied to directories such as /tmp which must be publicly writable but should deny users the licence to arbitrarily delete or rename each others' files.

[Note that 'text' doesn't mean what you might think it means in this context - it means 'code'. Note as well it's still possible to apply the sticky bit to files other than directories - it just doesn't have any effect.]

Any user may create a sticky directory. The sticky bit is used in the root of your file system to help prevent things from disappearing. Subdirectories can always be protected by their parent directories but not root. The sticky bit becomes very useful here.

The example given with /tmp is easy to understand: a Unix computer can have any number of users (perhaps using fast user switching) but there's only one /tmp. The directory wears the sticky bit so one user can't delete files belonging to another user.

Set ID Bits

The set ID bits are a breed apart. They're part and parcel of the Unix security system and one of the many reasons Unix can be used securely (whilst that other system known as 'Windows' cannot).

Unix files can have either or both of the set ID bits - set group ID (or set GID or SGID) and set user ID (or set UID or SUID). These bits affect only executables.

An executable in this context is anything that runs. It could be a script or it could be a compiled and linked binary. Such as found in /bin, /sbin, /usr/bin, /usr/sbin for example. Such as you have at the relative path Contents/MacOS in your Cocoa bundles on Mac OS X (or at a much shorter path on your iPhone with the iPhone OS).

Normally your OS kernel won't act on script files with set ID bits - for reasons you may shortly understand. This is a configurable option when building a Unix kernel but it's just not a good idea and is rarely used. But set ID bits on binary executables are common. How do they work?

First off: to have any effect at all, you as user must already have permission to run the binary. You can see these permissions directly in the 'bin' directories or by inspecting the Cocoa binaries at the relative path Contents/MacOS. If the file's permissions don't grant you access, then the set ID bits won't help you.

But given that you can run the file, then a number of things can happen. The set group ID bit means that as long as you're running that program - and only in the process context of that program - you will effectively be a member of the file's group. The set user ID bit means that as long as you're running that program - and only in the process context of that program - you are effectively the file's owner.

Running a Cocoa bundle with a binary set to ownership root:wheel (top dog on a Unix box) and permissions 6555 will make you root for your run of that program.

[Yes this looks extremely dangerous. It is.]

Studying sudo offers a case in point.


sudo - substitute user and do - is an offshoot of the Unix standard su (substitute user) initially developed for OpenBSD but found on most Unix platforms today. It's thought to be safer than su because it doesn't open a root account permanently but only executes one command as another user (by default root) before exiting and turning your carriage into a pumpkin again.

But look at sudo on disk and you should immediately understand how and why it works. The ACP framework info sheet reveals this.

The more explicit Xattrib reveals this too.

Note who owns sudo: root:wheel, by definition the real root on the system, the superuser. The superuser can do almost anything. This gives sudo the ability to execute any command in any context and as any user.

Note the mode: 4511. No one but root can even read the file. Note the SUID bit is set.

This means very simply that any command run through sudo will by default run as root. That's rather powerful. (It should therefore come as no surprise that most of sudo's code is spent checking that the program isn't being exploited.)

Users who can pass through the sudo turnstile can run commands as any user - precisely because they #1) are allowed to run sudo; and 2) sudo has the set user ID bit set so they're running it as root.

[Theory isn't practice: in practice, sudo uses configuration files to determine who's allowed to escalate in this fashion and who is not.]

Note finally how sudo is deep down in a directory hierarchy and well protected. There is no way any user (save root) can get at that file or even its directory.

Further Reading
ACP Users: More File Stuff (2)
Learning Curve: Files, Ownership, Permissions, Stuff Like That
Learning Curve: Files, Ownership, Permissions, Stuff Like That (2)

About | ACP | Get Stuff | Industry Watch | Learning Curve | Newsletter | Search | Test Drive
Copyright © Rixstep. All rights reserved.