特殊パーミッション
パーミッションには、いつもの3桁の上にもう1桁あります。4755 の先頭の 4 が何なのかを説明できないと、ls -l に出る s や t も読めません。
| ビット | 8進数 | シンボル | 意味 |
|---|---|---|---|
| SUID | 4000 | u+s | 実行時にファイル所有者の権限で動く |
| SGID | 2000 | g+s | 実行時にファイルのグループ権限で動く。ディレクトリではグループを継承 |
| スティッキー | 1000 | +t | ディレクトリ内で自分のファイルしか削除できなくなる |
一般ユーザーが自分のパスワードを変えられる理由
SUID が付いた実行ファイルは、誰が実行してもファイル所有者の権限で動きます。代表例が /usr/bin/passwd です。パスワードの変更には root しか書けない /etc/shadow を書き換える必要がありますが、passwd に SUID が付いていて root 権限で動くので、一般ユーザーでも自分のパスワードを変えられます。
プレーンテキスト
-rwsr-xr-x 1 root root 68208 /usr/bin/passwd所有者の実行権の位置が x ではなく s になっています。実行権が無いまま SUID だけを付けると、小文字ではなく大文字の S が出ます。SUID は設定されているが実行できない、という無意味な状態を示す警告で、この大文字と小文字の違いが試験で問われます。
SUID は強力なぶん危険です。設定されたプログラムに脆弱性があれば、そのまま root 権限を奪われます。棚卸しは定番のセキュリティ作業です。
ターミナル
find / -perm -4000 -type f 2>/dev/null-perm -4000 の先頭のハイフンは「少なくともこのビットが立っている」という意味です。ハイフンなしの -perm 4000 は「ちょうど 4000 と完全一致」になり、実質何も見つかりません。SGID なら -perm -2000、スティッキーなら -perm -1000 です。
チームの共有ディレクトリで SGID が効く
ファイルに付けた SGID は SUID のグループ版で、実行時にファイルのグループ権限で動き、ls -l ではグループの実行権の位置が s になります。
より実用的なのはディレクトリに付けた場合です。SGID 付きディレクトリの中に作られたファイルとディレクトリは、作成者のプライマリグループではなく、そのディレクトリのグループを継承します。サブディレクトリには SGID 自体も引き継がれます。
/srv/project に SGID とグループ dev を設定しておけば、誰がファイルを置いてもグループは dev になり、チーム全員が読み書きできます。SGID が無いと各自のプライマリグループになってしまい、他のメンバーが触れません。
/tmp が誰でも書けるのに荒らされない理由
スティッキービットをディレクトリに付けると、その中のファイルは、ファイルの所有者かディレクトリの所有者か root しか削除できなくなります。書き込み権があっても他人のファイルは消せません。
プレーンテキスト
drwxrwxrwt 12 root root 4096 /tmp全ユーザーが自由にファイルを作れる必要がある一方で、他人の一時ファイルを勝手に消されては困ります。この2つを両立させるのがスティッキービットです。裏を返せば、スティッキーの無い 777 は誰でも他人のファイルを消せる状態なので、共有ディレクトリを 777 にするのは避けてください。ここでも実行権が無ければ大文字の T になります。
4桁と ls -l の対応
| 8進数 | ls -l の表示 | 意味 |
|---|---|---|
| 4755 | -rwsr-xr-x | SUID 付きの実行ファイル |
| 2775 | drwxrwsr-x | SGID 付きの共有ディレクトリ |
| 1777 | drwxrwxrwt | スティッキー付きの誰でも書けるディレクトリ |
| 6755 | -rwsr-sr-x | SUID と SGID の両方 |
設定は数値でも、chmod u+s chmod g+s chmod +t のようにシンボルでも書けます。確認は ls -l の表示のほか、stat -c %a で8進数だけを取り出せます。
試験で狙われるところ
SUID は 4000、SGID は 2000、スティッキーは 1000 です。実行権が無いまま特殊ビットを付けると大文字の S や T になります。SGID のグループ継承はディレクトリに付けたときの話です。スティッキービットはディレクトリにのみ有効で、ファイルに付けても効きません。そして find -perm 4000 と -perm -4000 は別物です。