*参照元 [#bb8f98fb]
#backlinks

*説明 [#ne4e0383]
-パス: [[linux-2.6.33/]]
-パス: [[linux-2.6.33/fs/exec.c]]

-FIXME: これは何?
--説明


**引数 [#v5ef7b8c]
-
--

**返り値 [#kf68d436]
-
--

**参考 [#x4cea0c9]


*実装 [#pc820f02]
 void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 {
 	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 dumpable, bail out.
 	 */
 	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 know it
 	 *	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 might
 	 * be seen by the filesystem code called to write the core file.
 	 */
 	clear_thread_flag(TIF_SIGPENDING);
-
--[[linux-2.6.33/clear_thread_flag()]]

 
 	/*
 	 * lock_kernel() because format_corename() is controlled by sysctl, which
 	 * 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 things
 			 * 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\n",
 			       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, &helper_argc);
 		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_argv, NULL,
 				&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 named pipes etc.,
 	   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 coredump
 	 * 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.file) != 0)
 		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]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS