linux-2.6.33/do_coredump()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#bb8f98fb]
#backlinks
*説明 [#ne4e0383]
-パス: [[linux-2.6.33/fs/exec.c]]
-FIXME: これは何?
--説明
**引数 [#v5ef7b8c]
-
--
**返り値 [#kf68d436]
-
--
**参考 [#x4cea0c9]
*実装 [#pc820f02]
void do_coredump(long signr, int exit_code, struct pt_re...
{
struct core_state core_state;
-
--[[linux-2.6.33/core_state]]
char corename[CORENAME_MAX_SIZE + 1];
struct mm_struct *mm = current->mm;
-
--[[linux-2.6.33/mm_struct]]
struct linux_binfmt * binfmt;
-
--[[linux-2.6.33/linux_binfmt]]
struct inode * inode;
-
--[[linux-2.6.33/inode]]
const struct cred *old_cred;
struct cred *cred;
-
--[[linux-2.6.33/cred]]
int retval = 0;
int flag = 0;
int ispipe = 0;
char **helper_argv = NULL;
int helper_argc = 0;
int dump_count = 0;
static atomic_t core_dump_count = ATOMIC_INIT(0);
-
--[[linux-2.6.33/atomic_t]]
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
.limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
};
-
--[[linux-2.6.33/coredump_params]]
audit_core_dumps(signr);
-
--[[linux-2.6.33/audit_core_dumps()]]
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
cred = prepare_creds();
if (!cred) {
retval = -ENOMEM;
goto fail;
}
-
--[[linux-2.6.33/prepare_creds()]]
down_write(&mm->mmap_sem);
-
--[[linux-2.6.33/down_write()]]
/*
* If another thread got here first, or we are not dump...
*/
if (mm->core_state || !get_dumpable(mm)) {
up_write(&mm->mmap_sem);
put_cred(cred);
goto fail;
}
-
--[[linux-2.6.33/get_dumpable()]]
-
--[[linux-2.6.33/up_write()]]
-
--[[linux-2.6.33/put_cred()]]
/*
* We cannot trust fsuid as being the "true" uid of the
* process nor do we know its entire history. We only k...
* was tainted so we dump it as root in mode 2.
*/
if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
flag = O_EXCL; /* Stop rewrite attacks */
cred->fsuid = 0; /* Dump root private */
}
retval = coredump_wait(exit_code, &core_state);
if (retval < 0) {
put_cred(cred);
goto fail;
}
-
--[[linux-2.6.33/coredump_wait()]]
old_cred = override_creds(cred);
-
--[[linux-2.6.33/override_creds()]]
/*
* Clear any false indication of pending signals that m...
* be seen by the filesystem code called to write the c...
*/
clear_thread_flag(TIF_SIGPENDING);
-
--[[linux-2.6.33/clear_thread_flag()]]
/*
* lock_kernel() because format_corename() is controlle...
* uses lock_kernel()
*/
lock_kernel();
-
--[[linux-2.6.33/lock_kernel()]]
ispipe = format_corename(corename, signr);
-
--[[linux-2.6.33/format_corename()]]
unlock_kernel();
-
--[[linux-2.6.33/unlock_kernel()]]
if ((!ispipe) && (cprm.limit < binfmt->min_coredump))
goto fail_unlock;
if (ispipe) {
if (cprm.limit == 0) {
/*
* Normally core limits are irrelevant to pipes, since
* we're not writing to the file system, but we use
* cprm.limit of 0 here as a speacial value. Any
* non-zero limit gets set to RLIM_INFINITY below, but
* a limit of 0 skips the dump. This is a consistent
* way to catch recursive crashes. We can still crash
* if the core_pattern binary sets RLIM_CORE = !0
* but it runs as root, and can do lots of stupid thi...
* Note that we use task_tgid_vnr here to grab the pid
* of the process group leader. That way we get the
* right pid if a thread in a multi-threaded
* core_pattern process dies.
*/
printk(KERN_WARNING
"Process %d(%s) has RLIMIT_CORE set to 0\n",
task_tgid_vnr(current), current->comm);
printk(KERN_WARNING "Aborting core\n");
goto fail_unlock;
}
-
--[[linux-2.6.33/task_tgid_vnr()]]
dump_count = atomic_inc_return(&core_dump_count);
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\...
task_tgid_vnr(current), current->comm);
printk(KERN_WARNING "Skipping core dump\n");
goto fail_dropcount;
}
-
--[[linux-2.6.33/atomic_inc_return()]]
helper_argv = argv_split(GFP_KERNEL, corename+1, &help...
if (!helper_argv) {
printk(KERN_WARNING "%s failed to allocate memory\n",
__func__);
goto fail_dropcount;
}
-
--[[linux-2.6.33/argv_split()]]
cprm.limit = RLIM_INFINITY;
/* SIGPIPE can happen, but it's just never processed */
if (call_usermodehelper_pipe(helper_argv[0], helper_ar...
&cprm.file)) {
printk(KERN_INFO "Core dump to %s pipe failed\n",
corename);
goto fail_dropcount;
}
-
--[[linux-2.6.33/call_usermodehelper_pipe()]]
} else
cprm.file = filp_open(corename,
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
0600);
-
--[[linux-2.6.33/filp_open()]]
if (IS_ERR(cprm.file))
goto fail_dropcount;
inode = cprm.file->f_path.dentry->d_inode;
if (inode->i_nlink > 1)
goto close_fail; /* multiple links - don't dump */
if (!ispipe && d_unhashed(cprm.file->f_path.dentry))
goto close_fail;
-
--[[linux-2.6.33/IS_ERR()]]
-
--[[linux-2.6.33/d_unhashed()]]
/* AK: actually i see no reason to not allow this for n...
but keep the previous behaviour for now. */
if (!ispipe && !S_ISREG(inode->i_mode))
goto close_fail;
-
--[[linux-2.6.33/S_ISREG()]]
/*
* Dont allow local users get cute and trick others to ...
* into their pre-created files:
*/
if (inode->i_uid != current_fsuid())
goto close_fail;
if (!cprm.file->f_op)
goto close_fail;
if (!cprm.file->f_op->write)
goto close_fail;
if (!ispipe &&
do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.fi...
goto close_fail;
-
--[[linux-2.6.33/current_fsuid()]]
-
--[[linux-2.6.33/do_truncate()]]
retval = binfmt->core_dump(&cprm);
-
--[[linux-2.6.33/linux_binfmt]]
if (retval)
current->signal->group_exit_code |= 0x80;
close_fail:
if (ispipe && core_pipe_limit)
wait_for_dump_helpers(cprm.file);
-
--[[linux-2.6.33/wait_for_dump_helpers()]]
filp_close(cprm.file, NULL);
-
--[[linux-2.6.33/filp_close()]]
fail_dropcount:
if (dump_count)
atomic_dec(&core_dump_count);
-
--[[linux-2.6.33/atomic_dec()]]
fail_unlock:
if (helper_argv)
argv_free(helper_argv);
-
--[[linux-2.6.33/argv_free()]]
revert_creds(old_cred);
-
--[[linux-2.6.33/revert_creds()]]
put_cred(cred);
-
--[[linux-2.6.33/put_cred()]]
coredump_finish(mm);
-
--[[linux-2.6.33/coredump_finish()]]
fail:
return;
}
*コメント [#j2c70d2e]
終了行:
*参照元 [#bb8f98fb]
#backlinks
*説明 [#ne4e0383]
-パス: [[linux-2.6.33/fs/exec.c]]
-FIXME: これは何?
--説明
**引数 [#v5ef7b8c]
-
--
**返り値 [#kf68d436]
-
--
**参考 [#x4cea0c9]
*実装 [#pc820f02]
void do_coredump(long signr, int exit_code, struct pt_re...
{
struct core_state core_state;
-
--[[linux-2.6.33/core_state]]
char corename[CORENAME_MAX_SIZE + 1];
struct mm_struct *mm = current->mm;
-
--[[linux-2.6.33/mm_struct]]
struct linux_binfmt * binfmt;
-
--[[linux-2.6.33/linux_binfmt]]
struct inode * inode;
-
--[[linux-2.6.33/inode]]
const struct cred *old_cred;
struct cred *cred;
-
--[[linux-2.6.33/cred]]
int retval = 0;
int flag = 0;
int ispipe = 0;
char **helper_argv = NULL;
int helper_argc = 0;
int dump_count = 0;
static atomic_t core_dump_count = ATOMIC_INIT(0);
-
--[[linux-2.6.33/atomic_t]]
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
.limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
};
-
--[[linux-2.6.33/coredump_params]]
audit_core_dumps(signr);
-
--[[linux-2.6.33/audit_core_dumps()]]
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
cred = prepare_creds();
if (!cred) {
retval = -ENOMEM;
goto fail;
}
-
--[[linux-2.6.33/prepare_creds()]]
down_write(&mm->mmap_sem);
-
--[[linux-2.6.33/down_write()]]
/*
* If another thread got here first, or we are not dump...
*/
if (mm->core_state || !get_dumpable(mm)) {
up_write(&mm->mmap_sem);
put_cred(cred);
goto fail;
}
-
--[[linux-2.6.33/get_dumpable()]]
-
--[[linux-2.6.33/up_write()]]
-
--[[linux-2.6.33/put_cred()]]
/*
* We cannot trust fsuid as being the "true" uid of the
* process nor do we know its entire history. We only k...
* was tainted so we dump it as root in mode 2.
*/
if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
flag = O_EXCL; /* Stop rewrite attacks */
cred->fsuid = 0; /* Dump root private */
}
retval = coredump_wait(exit_code, &core_state);
if (retval < 0) {
put_cred(cred);
goto fail;
}
-
--[[linux-2.6.33/coredump_wait()]]
old_cred = override_creds(cred);
-
--[[linux-2.6.33/override_creds()]]
/*
* Clear any false indication of pending signals that m...
* be seen by the filesystem code called to write the c...
*/
clear_thread_flag(TIF_SIGPENDING);
-
--[[linux-2.6.33/clear_thread_flag()]]
/*
* lock_kernel() because format_corename() is controlle...
* uses lock_kernel()
*/
lock_kernel();
-
--[[linux-2.6.33/lock_kernel()]]
ispipe = format_corename(corename, signr);
-
--[[linux-2.6.33/format_corename()]]
unlock_kernel();
-
--[[linux-2.6.33/unlock_kernel()]]
if ((!ispipe) && (cprm.limit < binfmt->min_coredump))
goto fail_unlock;
if (ispipe) {
if (cprm.limit == 0) {
/*
* Normally core limits are irrelevant to pipes, since
* we're not writing to the file system, but we use
* cprm.limit of 0 here as a speacial value. Any
* non-zero limit gets set to RLIM_INFINITY below, but
* a limit of 0 skips the dump. This is a consistent
* way to catch recursive crashes. We can still crash
* if the core_pattern binary sets RLIM_CORE = !0
* but it runs as root, and can do lots of stupid thi...
* Note that we use task_tgid_vnr here to grab the pid
* of the process group leader. That way we get the
* right pid if a thread in a multi-threaded
* core_pattern process dies.
*/
printk(KERN_WARNING
"Process %d(%s) has RLIMIT_CORE set to 0\n",
task_tgid_vnr(current), current->comm);
printk(KERN_WARNING "Aborting core\n");
goto fail_unlock;
}
-
--[[linux-2.6.33/task_tgid_vnr()]]
dump_count = atomic_inc_return(&core_dump_count);
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\...
task_tgid_vnr(current), current->comm);
printk(KERN_WARNING "Skipping core dump\n");
goto fail_dropcount;
}
-
--[[linux-2.6.33/atomic_inc_return()]]
helper_argv = argv_split(GFP_KERNEL, corename+1, &help...
if (!helper_argv) {
printk(KERN_WARNING "%s failed to allocate memory\n",
__func__);
goto fail_dropcount;
}
-
--[[linux-2.6.33/argv_split()]]
cprm.limit = RLIM_INFINITY;
/* SIGPIPE can happen, but it's just never processed */
if (call_usermodehelper_pipe(helper_argv[0], helper_ar...
&cprm.file)) {
printk(KERN_INFO "Core dump to %s pipe failed\n",
corename);
goto fail_dropcount;
}
-
--[[linux-2.6.33/call_usermodehelper_pipe()]]
} else
cprm.file = filp_open(corename,
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
0600);
-
--[[linux-2.6.33/filp_open()]]
if (IS_ERR(cprm.file))
goto fail_dropcount;
inode = cprm.file->f_path.dentry->d_inode;
if (inode->i_nlink > 1)
goto close_fail; /* multiple links - don't dump */
if (!ispipe && d_unhashed(cprm.file->f_path.dentry))
goto close_fail;
-
--[[linux-2.6.33/IS_ERR()]]
-
--[[linux-2.6.33/d_unhashed()]]
/* AK: actually i see no reason to not allow this for n...
but keep the previous behaviour for now. */
if (!ispipe && !S_ISREG(inode->i_mode))
goto close_fail;
-
--[[linux-2.6.33/S_ISREG()]]
/*
* Dont allow local users get cute and trick others to ...
* into their pre-created files:
*/
if (inode->i_uid != current_fsuid())
goto close_fail;
if (!cprm.file->f_op)
goto close_fail;
if (!cprm.file->f_op->write)
goto close_fail;
if (!ispipe &&
do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.fi...
goto close_fail;
-
--[[linux-2.6.33/current_fsuid()]]
-
--[[linux-2.6.33/do_truncate()]]
retval = binfmt->core_dump(&cprm);
-
--[[linux-2.6.33/linux_binfmt]]
if (retval)
current->signal->group_exit_code |= 0x80;
close_fail:
if (ispipe && core_pipe_limit)
wait_for_dump_helpers(cprm.file);
-
--[[linux-2.6.33/wait_for_dump_helpers()]]
filp_close(cprm.file, NULL);
-
--[[linux-2.6.33/filp_close()]]
fail_dropcount:
if (dump_count)
atomic_dec(&core_dump_count);
-
--[[linux-2.6.33/atomic_dec()]]
fail_unlock:
if (helper_argv)
argv_free(helper_argv);
-
--[[linux-2.6.33/argv_free()]]
revert_creds(old_cred);
-
--[[linux-2.6.33/revert_creds()]]
put_cred(cred);
-
--[[linux-2.6.33/put_cred()]]
coredump_finish(mm);
-
--[[linux-2.6.33/coredump_finish()]]
fail:
return;
}
*コメント [#j2c70d2e]
ページ名: