|
@@ -418,6 +418,17 @@ static void coredump_finish(struct mm_struct *mm, bool core_dumped)
|
|
|
mm->core_state = NULL;
|
|
|
}
|
|
|
|
|
|
+static bool dump_interrupted(void)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * SIGKILL or freezing() interrupt the coredumping. Perhaps we
|
|
|
+ * can do try_to_freeze() and check __fatal_signal_pending(),
|
|
|
+ * but then we need to teach dump_write() to restart and clear
|
|
|
+ * TIF_SIGPENDING.
|
|
|
+ */
|
|
|
+ return signal_pending(current);
|
|
|
+}
|
|
|
+
|
|
|
static void wait_for_dump_helpers(struct file *file)
|
|
|
{
|
|
|
struct pipe_inode_info *pipe;
|
|
@@ -641,7 +652,7 @@ void do_coredump(siginfo_t *siginfo)
|
|
|
goto close_fail;
|
|
|
if (displaced)
|
|
|
put_files_struct(displaced);
|
|
|
- core_dumped = binfmt->core_dump(&cprm);
|
|
|
+ core_dumped = !dump_interrupted() && binfmt->core_dump(&cprm);
|
|
|
|
|
|
if (ispipe && core_pipe_limit)
|
|
|
wait_for_dump_helpers(cprm.file);
|
|
@@ -669,7 +680,9 @@ fail:
|
|
|
*/
|
|
|
int dump_write(struct file *file, const void *addr, int nr)
|
|
|
{
|
|
|
- return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
|
|
|
+ return !dump_interrupted() &&
|
|
|
+ access_ok(VERIFY_READ, addr, nr) &&
|
|
|
+ file->f_op->write(file, addr, nr, &file->f_pos) == nr;
|
|
|
}
|
|
|
EXPORT_SYMBOL(dump_write);
|
|
|
|
|
@@ -678,7 +691,8 @@ int dump_seek(struct file *file, loff_t off)
|
|
|
int ret = 1;
|
|
|
|
|
|
if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
|
|
|
- if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
|
|
|
+ if (dump_interrupted() ||
|
|
|
+ file->f_op->llseek(file, off, SEEK_CUR) < 0)
|
|
|
return 0;
|
|
|
} else {
|
|
|
char *buf = (char *)get_zeroed_page(GFP_KERNEL);
|