What did the sticky bit originally do when applied to files

historypermissionssticky-bit

In various places one can see the "sticky bit" accused of nowadays being a complete misnomer, as its functionality nowadays is to affect the write permissions on directories and act as a restricted deletion flag.

In an AskUbuntu answer the answerer wrote that "a sticky bit usually applies to directories". I observed that indeed modern systems seem in practice to never apply it to files, but that a long time ago the usual case was for it to apply to (executable program image) files rather than to directories. (When it comes to the paucity of modern usage on files, there's a related question at Is the sticky bit not used in current file systems .)

This prompted the question:

What did a sticky bit applied to an executable do? Was it like setuid then?

Note the past tense. This is not How does the sticky bit work? now. It's how it used to work then.

Best Answer

No, the sticky bit was not like the set-UID or set-GID flags. It didn't effect any changes to process credentials.

What the sticky bit did was make the program text "sticky". It wasn't a misnomer, originally.

background: program image sections and shared text

In essence, without getting too deep into the details of executable file formats (which can, and have, filled books): The parts of program image files that are directly loaded into memory in order to run programs comprise machine code, constants, the startup values of (non-zero-initialized) variables, and (in one form or another) blank spaces for zero-initialized and uninitialized variables.

These are grouped into collections known as "sections" and they have conventional names. The machine code and (sometimes) the constants form what is often known as the "text" section of a program image. The non-zero-initialized variables are, similarly, the "data" section; and the zero-initialized and uninitialized variables are "bss" (a name which itself has a whole folkloric history behind it).

When a process has a program executable image file loaded into it, the various parts — text, data, and bss — are initialized from the contents of the image file.

What's special about the "text" section is that the machine code (and the constants) is almost always not written to. It has the potential to be shared across the virtual memory images of all executing process that had that executable image file loaded into them. The exact scenario in which program text can be shared is out of scope for this answer and involves things such as loader fixup idempotence and address space layout identity. People can and have written books about this subject, too. ☺

Shared text is an optimization employed by the kernel. It removes the need for every instance of a single running program image to have its own individual memory image, consuming precious physical memory with multiple copies of the exact same machine code (and constants).

sticky text

But one can do better still than shared text. Obviously, if there's always at least one process running that is using a particular shared text program image, the kernel gets to simply attach the new processes' virtual memory space to the existing shared text segment when a new instance of the program is run. There's almost always an instance of (say) /bin/login or /bin/sh running somewhere on a mid-sized system, so new instances of the login program or the default shell can simply attach to the loaded copies of their text segments that the kernel has already loaded into memory.

Sticky text extends this idea to program images that no process is currently running. If an executable image file is marked as sticky text, then the kernel keeps its text segment around after the last process to use it exits; in the hope that another instance of the program will execute soon, and can just attach back to the segment.

In early Unices, loaded sticky text segments would be swapped out to swap storage when no process was attached to them. (Later Unices stopped using swap for this.) You might also have heard of this by the name saved text.

Of course, setting the sticky text bit on a program image is something that has to be done with care. What programs benefit from it depend from what the machine is generally used for. And currently unattached text segments take up kernel resources, meaning that there is a practical limit to how many one can have in any system. So it is generally an operation that requires superuser privileges.

desuetude

There is a whole load of assumptions that underlies the operation of sticky text, that just aren't true any more. Reading a pre-made segment from swap storage isn't necessarily faster than simple demand paging in from the actual executable image file. Filesystem formats became better for random (as opposed to sequential) reading patterns. The advent of demand paging itself changes things, as do things like unified caches, non-idempotent external fixups resulting from differences in shared library search, and address space layout randomization.

The days of sticky text bits for executable program images are long gone. An explicit sticky text marker flag for executable program images was considered obsolete by the writers of 4.3BSD in the mid-1980s, for example.

Further reading

  • Maurice J. Bach (1986). The Design of the UNIX Operating System. Prentice-Hall. ISBN 9780132017992.