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でコールする必要があります。




