03-C.4.2: Special Permission Types - The Sticky Bit
- Page ID
- 26827
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)The Sticky Bit
The sticky bit was initially introduced to ‘stick’ an executable program’s text segment in the swap space even after the program has completed execution, in order to speed up the subsequent runs of the same program. However, these days the sticky bit means something entirely different.
When a directory has the sticky bit set, its files can be deleted or renamed only by the file owner, directory owner and the root user. The command below shows how the sticky bit can be set.
chmod +t filename
Simply look for a ‘t’ character in the file permissions to locate the sticky bit. The snippet below shows how we can set the sticky bit for some directory “Gatos,” and how it prevents the new user from deleting a file in the directory.
Here is a directory called Personnel. It has a permission of 777 (rwxrwxrwx)- the user, the group and all the rest of the world have read, write and execute permissions. The directory has 2 files in it. The xyz.txt file also has wide open permissions.
pbmac@pbmac-server $ ls -l
drwxrwxrwx 2 pbmac pbmac 4096 Jun 5 16:23 Personnel
pbmac@pbmac-server $ ls -l Personnel/
-rw-r--r-- 1 pbmac pbmac 0 Jun 4 17:51 PersonnelFile-1.txt
-rwxrwxrwx 1 pbmac pbmac 0 Jun 5 16:23 xyz.txt
Use the chmod command to add the sticky bit, and an ls -l confirms the sticky bit is now set. Switch users to santiago, and cd into the Personnel directory, and attempt to remove the xyz.txt file - it fails due to the sticky bit being set on the directory where this file lives. Exit from the user santiago.
pbmac@pbmac-server $ chmod +t Personnel/
pbmac@pbmac-server $ su santiago
Password:
santiago@pbmac-server $ cd Personnel/
santiago@pbmac-server $ rm xyz.txt
rm: cannot remove 'xyz.txt': Operation not permitted
santiago@pbmac-server $
As user pbmac, the sticky bit is removed using the chmod command. Switch users to santiago, and cd into the Personnel directory, and attempt to remove the xyz.txt file - success, because the directory has rwxrwxrwx as does the file.
pbmac@pbmac-server $ chmod -t Personnel/
pbmac@pbmac-server $ ls -l
drwxrwxrwx 2 pbmac pbmac 4096 Jun 5 16:23 Personnel
pbmac@pbmac-server $ su santiago
Password:
santiago@pbmac-server $ cd Personnel/
santiago@pbmac-server $ rm xyz.txt
santiago@pbmac-server $ ls
PersonnelFile-1.txt
As shown above, to remove the sticky bit, simply use the following command:
chmod -t filename
Since deleting a file is controlled by the write permission of the file, practical uses of the sticky bit involve world-writable directories such as ‘/tmp’ so that the delete permissions are reserved only for the owners of the file.
Note that each of these bits can also be set in octal format with SUID=4, SGID=2, and Sticky=1.
Set the SETUID bit
pbmac@pbmac-server $ chmod 4744 filename
Set the SGID bit
pbmac@pbmac-server $ chmod 2644 filename
Set the Sticky bit
pbmac@pbmac-server $ chmod 1755 filename
Uppercase or Lowercase?
If you are setting the special bits and see an uppercase S or T instead of lowercase (as we've seen until this point), it is because the underlying execute bit is not present. To demonstrate, the following example creates a file with the sticky bit set. We can then add/remove the execute bit to demonstrate the case change.
pbmac@pbmac-server $ chmod 1755 cap-ST-demo
pbmac@pbmac-server $ ls -l cap-ST-demo
-rwxr-xr-t 1 root root 0 Jun 12 06:16 cap-ST-demo
Now - remove the execute permission from the other and see what happens
pbmac@pbmac-server $ chmod o-x cap-X-demo
pbmac@pbmac-server $ ls -l cap-X-demo
-rwxr-xr-T 1 root root 0 Jun 12 06:16 cap-ST-demo
Setting the Execute Bit Conditionally
To this point, we've set the execute bit using a lowercase x, which sets it without asking any questions. We have another option: using an uppercase X instead of lowercase will set the execute bit only if it is already present somewhere in the permission group. This can be a difficult concept to explain, but the demo below will help illustrate it. Notice here that after trying to add the execute bit to the group privileges, it is not applied.
pbmac@pbmac-server $ ls -l cap-X-file
-rw-r--r-- 1 root root 0 Jun 12 06:31 cap-X-file
pbmac@pbmac-server $ chmod g+X cap-X-file
Notice - the file does NOT accept the addition of the X permission
pbmac@pbmac-server $ ls -l cap-X-file
-rw-r--r-- 1 root root 0 Jun 12 06:31 cap-X-file
In this similar example, we add the execute bit first to the group permissions using the lowercase x and then use the uppercase X to add permissions for all other users. This time, the uppercase X sets the permissions.
pbmac@pbmac-server $ ls -l cap-X-file
-rw-r--r-- 1 root root 0 Jun 12 06:31 cap-X-file
Add x permission to the group
pbmac@pbmac-server chmod g+x cap-X-file
pbmac@pbmac-server $ ls -l cap-X-file
-rw-r-xr-- 1 root root 0 Jun 12 06:31 cap-X-file
Now try with the upper case X
pbmac@pbmac-server $ chmod o+X cap-X-file
pbmac@pbmac-server $ ls -l cap-X-file
-rw-r-xr-x 1 root root 0 Jun 12 06:31 cap-X-file
Adapted from:
"Linux permissions 101" by Alex Juarez , OpenSource.com is licensed under CC BY-SA 4.0
"SetUID, SetGID, and Sticky Bits in Linux File Permissions" by Anannya Uberoi 1, Geeks for Geeks is licensed under CC BY-SA 4.0