umaskのデフォルト値について,カーネルのソースコードから /etc/の下の設定ファイルまで全部調べました.
作業メモを公開します.
umaskのデフォルト値
シェル(bash)から見ると, umask の初期値はディストリビューションによって異なります.
ディストリビューション | umaskの値(8進数) | (symbolic表現) |
redhat/centos | 0002 | u=rwx,g=rwx,o=rx |
debian | 0022 | u=rwx,g=rx,o=rx |
そもそも umask って何?
umaskは新規ファイルや新規ディレクトリの作成時のパーミッションを決める変数(マスク値)ですが,ここではその実装を調べます.
結論から言うとumaskの実体はシステムコールです.Linux のカーネル version 6.2.10 の場合,umaskは kernel/sys.c の1866行目で実装されています.
https://elixir.bootlin.com/linux/v6.2.10/source/kernel/sys.c#L1866
SYSCALL_DEFINE1(umask, int, mask) { mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; }
大雑把に言うと,プロセス毎に割り当てられたメモリ領域があって,そこにumaskという変数が割り当てられています.ファイルやディレクトリを新規作成する場合は適宜 umaskの変数の値が参照されます.
umaskの値を変更するには,ユーザー空間からは
- umask コマンド(bashの場合は build-in)
- libcの umask関数
umaskのデフォルト値はどこで設定されている?
カーネルのソースコードを調べて, fs->umask の値を設定している箇所を探します.
と言っても grepコマンドを使えば数秒で見つかります.
$ cd linux-6.2.10/kernel/ $ grep "fs->umask" . -r ./umh.c: current->fs->umask = 0022; ./sys.c: mask = xchg(¤t->fs->umask, mask & S_IRWXUGO);
該当箇所は2箇所だけです.umh.cとsys.c の2つです.
後者sys.cは上記のumaskシステムコールの実装ですから,初期値を設定しているのは前者の umh.c です.
umh.c を見てみます.冒頭のコメント文に以下の記載があります
/* * umh - the kernel usermode helper */
umhはUser Mode Helper の略だそうです.ソースを眺めると,ユーザー空間のプロセスを生成する際のヘルパ関数を実装していることが解ります.
fs->umask を初期化しているのは umh.c の 83 行目でした.
https://elixir.bootlin.com/linux/v6.2.10/source/kernel/umh.c#L83
/* * Initial kernel threads share ther FS with init, in order to * get the init root directory. But we've now created a new * thread that is going to execve a user process and has its own * 'struct fs_struct'. Reset umask to the default. */ current->fs->umask = 0022;
ということで,カーネルではumaskの初期値を0022に設定していました.
centOSの /etc の下を覗いてみる
centOSは bash を起動する際に umask コマンドを実行している可能性があります
/etc の下のファイルを片っ端から grep で見てみます
$ grep umask /etc -r
以下のファイルで umask 002 を実行していました
- /etc/bashrc
- /etc/profile
/etc/profileの該当箇所
# By default, we want umask to get set. This sets it for login shell # Current threshold for system reserved uid/gids is 200 # You could check uidgid reservation validity in # /usr/share/doc/setup-*/uidgid file if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi
/etc/bashrcの該当箇所
# By default, we want umask to get set. This sets it for non-login shell. # Current threshold for system reserved uid/gids is 200 # You could check uidgid reservation validity in # /usr/share/doc/setup-*/uidgid file if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi
コメントに書いてあるように uid/gid が200以上の場合は umaskが002,それ以外の場合は umask が022になる,ということです
debianでも確認してみる
一応 debian でも/etcの下を覗いてみます
$ grep umask /etc -r
/etc/login.defs で UMASKの記述が見つかりました.引用するとこんな感じ
# # Login configuration initializations: # # ERASECHAR Terminal ERASE character ('\010' = backspace). # KILLCHAR Terminal KILL character ('\025' = CTRL/U). # UMASK Default "umask" value. # # The ERASECHAR and KILLCHAR are used only on System V machines. # # UMASK is the default umask value for pam_umask and is used by # useradd and newusers to set the mode of the new home directories. # 022 is the "historical" value in Debian for UMASK # 027, or even 077, could be considered better for privacy # There is no One True Answer here : each sysadmin must make up his/her # mind. # # If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value # for private user groups, i. e. the uid is the same as gid, and username is # the same as the primary group name: for these, the user permissions will be # used as group permissions, e. g. 022 will become 002. # # Prefix these values with "0" to get octal, "0x" to get hexadecimal. # ERASECHAR 0177 KILLCHAR 025 UMASK 022
書いてあることは
- /etc/login.defs で UMASKの値が指定できる
- UMASKを参照するのは以下のモジュール・コマンド
さらに
- 0022 は "historical" な値
- 更に USERGROUPS_ENAB をyesに設定すると0022が0002になる場合がある(詳細は原文を読んでください)
とも書いてあります
ただし,手元のdebianは pam_umask を使用しておらず,/etc/login.defs の設定は利用されていませんでした.