umaskシステムコール
Rev.1を表示中。最新版はこちら。
umaskシステムコールは、引数のmaskをcurrent->fs->umaskに設定するだけです。S_IRWXUGOは8進数で、0777のバイナリで111/111/111です。下位ビットから3バイト単位で、Other/Group/Userです。#define S_IRWXU 00700 #define S_IRUSR 00400 #define S_IWUSR 00200 #define S_IXUSR 00100 #define S_IRWXG 00070 #define S_IRGRP 00040 #define S_IWGRP 00020 #define S_IXGRP 00010 #define S_IRWXO 00007 #define S_IROTH 00004 #define S_IWOTH 00002 #define S_IXOTH 00001 #define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) SYSCALL_DEFINE1(umask, int, mask) { mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; }ファイル作成は、 inode_operationsの.mknodコールバックでinodeが取得されます。ext3の.mknodは、ext3_mknod()で、ext3_new_inode()がコールされ、openフラグ/プロセスid等に準じたinodeが取得した後、ext3_init_acl()でACLの設定が行われます。
ext3_init_acl()でファイルがリンクでない時でPOSIX_ACLでもない時、inode->i_mode &= ~current_umask()で、current->fs->umaskの設定してあるビットがクリアされます。
POSIX_ACLは、CONFIG_EXT3_FS_POSIX_ACLでカーネルが作成されており、mountオプションのACLを設定してmountし、ファイルシステムに応じた、inode_operationsの.get_aclコールバックが定義されているケースで、この場合umaskは無視されます。
int ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; int error = 0; if (!S_ISLNK(inode->i_mode)) { if (test_opt(dir->i_sb, POSIX_ACL)) { acl = ext3_get_acl(dir, ACL_TYPE_DEFAULT); if (IS_ERR(acl)) return PTR_ERR(acl); } if (!acl) inode->i_mode &= ~current_umask(); } if (test_opt(inode->i_sb, POSIX_ACL) && acl) { if (S_ISDIR(inode->i_mode)) { error = ext3_set_acl(handle, inode, ACL_TYPE_DEFAULT, acl); if (error) goto cleanup; } error = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); if (error < 0) return error; if (error > 0) { error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); } } cleanup: posix_acl_release(acl); return error; }デフォルトのumaskは、group/otherの書き込みを禁止しています。
struct fs_struct init_fs = { .users = 1, .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), .seq = SEQCNT_ZERO, .umask = 0022, }; #define INIT_TASK(tsk) \ { \ : .children = LIST_HEAD_INIT(tsk.children), \ .sibling = LIST_HEAD_INIT(tsk.sibling), \ .group_leader = &tsk, \ RCU_INIT_POINTER(.real_cred, &init_cred), \ RCU_INIT_POINTER(.cred, &init_cred), \ .comm = INIT_TASK_COMM, \ .thread = INIT_THREAD, \ .fs = &init_fs, \ .files = &init_files, \ .signal = &init_signals, \ : }
補足
umaskシステムコールはカレントプロセスへの更新となり、従ってumaskコマンドは外部コマンドでなく、シェルプロセスから直接コールしています。その時のmaskは8進数としてシェルが処理します。gccでumaskをコールする場合、maskを8進数としてコールするなら、0を先頭に付加する必要があります。従ってumaskコマンドで10とする設定に準じ、umaskシステムコールを10でコールすると、umaskコマンドで12としてコールした結果となり、umaskシステムコールでは010でコールする必要があります。