linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] coredump: pass siginfo_t* to do_coredump() and below, not merely signr
@ 2012-09-12 23:38 Denys Vlasenko
  2012-09-12 23:38 ` [PATCH 2/2] coredump: add a new elf note with siginfo fields of the signal Denys Vlasenko
  2012-09-13 15:08 ` [PATCH 1/2] coredump: pass siginfo_t* to do_coredump() and below, not merely signr Oleg Nesterov
  0 siblings, 2 replies; 10+ messages in thread
From: Denys Vlasenko @ 2012-09-12 23:38 UTC (permalink / raw)
  To: Oleg Nesterov, linux-kernel, Andrew Morton, Amerigo Wang, Roland McGrath
  Cc: Denys Vlasenko

This is a preparatory patch for the introduction of NT_SIGINFO elf note.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 fs/binfmt_aout.c         |    2 +-
 fs/binfmt_elf.c          |   14 +++++++-------
 fs/binfmt_elf_fdpic.c    |    6 +++---
 fs/binfmt_flat.c         |    2 +-
 fs/coredump.c            |   10 +++++-----
 include/linux/binfmts.h  |    2 +-
 include/linux/coredump.h |    4 ++--
 kernel/signal.c          |    2 +-
 8 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index d146e18..3a65adf 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -89,7 +89,7 @@ static int aout_core_dump(struct coredump_params *cprm)
 	current->flags |= PF_DUMPCORE;
        	strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
 	dump.u_ar0 = offsetof(struct user, regs);
-	dump.signal = cprm->signr;
+	dump.signal = cprm->info->si_signo;
 	aout_dump_thread(cprm->regs, &dump);
 
 /* If the size of the dump file exceeds the rlimit, then see what would happen
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 1b4efbc..41a40de 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1479,7 +1479,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
 
 static int fill_note_info(struct elfhdr *elf, int phdrs,
 			  struct elf_note_info *info,
-			  long signr, struct pt_regs *regs)
+			  siginfo_t *siginfo, struct pt_regs *regs)
 {
 	struct task_struct *dump_task = current;
 	const struct user_regset_view *view = task_user_regset_view(dump_task);
@@ -1549,7 +1549,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
 	 * Now fill in each thread's information.
 	 */
 	for (t = info->thread; t != NULL; t = t->next)
-		if (!fill_thread_core_info(t, view, signr, &info->size))
+		if (!fill_thread_core_info(t, view, siginfo->si_signo, &info->size))
 			return 0;
 
 	/*
@@ -1712,14 +1712,14 @@ static int elf_note_info_init(struct elf_note_info *info)
 
 static int fill_note_info(struct elfhdr *elf, int phdrs,
 			  struct elf_note_info *info,
-			  long signr, struct pt_regs *regs)
+			  siginfo_t *siginfo, struct pt_regs *regs)
 {
 	struct list_head *t;
 
 	if (!elf_note_info_init(info))
 		return 0;
 
-	if (signr) {
+	if (siginfo->si_signo) {
 		struct core_thread *ct;
 		struct elf_thread_status *ets;
 
@@ -1737,13 +1737,13 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
 			int sz;
 
 			ets = list_entry(t, struct elf_thread_status, list);
-			sz = elf_dump_thread_status(signr, ets);
+			sz = elf_dump_thread_status(siginfo->si_signo, ets);
 			info->thread_status_size += sz;
 		}
 	}
 	/* now collect the dump for the current */
 	memset(info->prstatus, 0, sizeof(*info->prstatus));
-	fill_prstatus(info->prstatus, current, signr);
+	fill_prstatus(info->prstatus, current, siginfo->si_signo);
 	elf_core_copy_regs(&info->prstatus->pr_reg, regs);
 
 	/* Set up header */
@@ -1950,7 +1950,7 @@ static int elf_core_dump(struct coredump_params *cprm)
 	 * Collect all the non-memory information about the process for the
 	 * notes.  This also sets up the file header.
 	 */
-	if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
+	if (!fill_note_info(elf, e_phnum, &info, cprm->info, cprm->regs))
 		goto cleanup;
 
 	has_dumped = 1;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 3d8fae0..6554f54 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1641,7 +1641,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
 		goto cleanup;
 #endif
 
-	if (cprm->signr) {
+	if (cprm->info->si_signo) {
 		struct core_thread *ct;
 		struct elf_thread_status *tmp;
 
@@ -1660,13 +1660,13 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
 			int sz;
 
 			tmp = list_entry(t, struct elf_thread_status, list);
-			sz = elf_dump_thread_status(cprm->signr, tmp);
+			sz = elf_dump_thread_status(cprm->info->si_signo, tmp);
 			thread_status_size += sz;
 		}
 	}
 
 	/* now collect the dump for the current */
-	fill_prstatus(prstatus, current, cprm->signr);
+	fill_prstatus(prstatus, current, cprm->info->si_signo);
 	elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
 
 	segs = current->mm->map_count;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 178cb70..ebe6feb 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -107,7 +107,7 @@ static struct linux_binfmt flat_format = {
 static int flat_core_dump(struct coredump_params *cprm)
 {
 	printk("Process %s:%d received signr %d and should have core dumped\n",
-			current->comm, current->pid, (int) cprm->signr);
+			current->comm, current->pid, (int) cprm->info->si_signo);
 	return(1);
 }
 
diff --git a/fs/coredump.c b/fs/coredump.c
index 1935b4d..0027ec0 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -463,7 +463,7 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
 	return 0;
 }
 
-void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+void do_coredump(siginfo_t *info, struct pt_regs *regs)
 {
 	struct core_state core_state;
 	struct core_name cn;
@@ -477,7 +477,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 	bool need_nonrelative = false;
 	static atomic_t core_dump_count = ATOMIC_INIT(0);
 	struct coredump_params cprm = {
-		.signr = signr,
+		.info = info,
 		.regs = regs,
 		.limit = rlimit(RLIMIT_CORE),
 		/*
@@ -488,7 +488,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 		.mm_flags = mm->flags,
 	};
 
-	audit_core_dumps(signr);
+	audit_core_dumps(info->si_signo);
 
 	binfmt = mm->binfmt;
 	if (!binfmt || !binfmt->core_dump)
@@ -512,7 +512,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 		need_nonrelative = true;
 	}
 
-	retval = coredump_wait(exit_code, &core_state);
+	retval = coredump_wait(info->si_signo, &core_state);
 	if (retval < 0)
 		goto fail_creds;
 
@@ -524,7 +524,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 	 */
 	clear_thread_flag(TIF_SIGPENDING);
 
-	ispipe = format_corename(&cn, signr);
+	ispipe = format_corename(&cn, info->si_signo);
 
  	if (ispipe) {
 		int dump_count;
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 52fb2eb..f2d1445 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -74,7 +74,7 @@ struct linux_binprm {
 
 /* Function parameter for binfmt->coredump */
 struct coredump_params {
-	long signr;
+	siginfo_t *info;
 	struct pt_regs *regs;
 	struct file *file;
 	unsigned long limit;
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 42f9752..be939ce 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -12,9 +12,9 @@
 extern int dump_write(struct file *file, const void *addr, int nr);
 extern int dump_seek(struct file *file, loff_t off);
 #ifdef CONFIG_COREDUMP
-extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
+extern void do_coredump(siginfo_t *info, struct pt_regs *regs);
 #else
-static inline void do_coredump(long signr, int exit_code, struct pt_regs *regs) {}
+static inline void do_coredump(siginfo_t *info, struct pt_regs *regs) {}
 #endif
 
 #endif /* _LINUX_COREDUMP_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index fb4fd72..546f23d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2370,7 +2370,7 @@ relock:
 			 * first and our do_group_exit call below will use
 			 * that value and ignore the one we pass it.
 			 */
-			do_coredump(info->si_signo, info->si_signo, regs);
+			do_coredump(info, regs);
 		}
 
 		/*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] coredump: add a new elf note with siginfo fields of the signal
@ 2012-09-13 14:31 Jonathan M. Foote
  0 siblings, 0 replies; 10+ messages in thread
From: Jonathan M. Foote @ 2012-09-13 14:31 UTC (permalink / raw)
  To: linux-kernel

Hello,

I am the author of the CERT 'exploitable' GDB extension (code here: http://www.cert.org/vuls/discovery/triage.html). The extension uses GDB to give developers information about how exploitable an application crash might be. Right now the extension can only supply useful information for live GDB targets. Denys's patches will allow the extension to work on core files as well, which will enable more teams performing crash triage to use the tool.

As a specific example of how this is useful, in the case of an access violation the extension applies heuristics that try to determine if the access violation was due to a read (si_addr == op.source) or a write (si_addr == op.dest). Write access violations _generally_ require less effort to exploit than read access violations, so, depending on what other heuristics can be applied, the extension may consider a write access violation to be more "more exploitable" than a read access violation. This information is helpful to developers who may have large numbers of crashing test cases to deal with and need to decide which ones to address first. 

As it stands, core files do not include si_addr, and so the 'exploitable' GDB extension is unable to produce even the most basic analysis when applied to them. Denys's patch aims to address this issue, and will therefore allow the 'exploitable' extension to produce some useful information when executed against core files. Since core files have become the standard method of communicating crash information in many contexts, these patches will allow for increased application of the 'exploitable' extension and in a small way promote greater software security for Linux applications.

Please consider accepting these patches.

Thanks,
Jonathan


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-09-17 10:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-12 23:38 [PATCH 1/2] coredump: pass siginfo_t* to do_coredump() and below, not merely signr Denys Vlasenko
2012-09-12 23:38 ` [PATCH 2/2] coredump: add a new elf note with siginfo fields of the signal Denys Vlasenko
2012-09-13 15:36   ` Oleg Nesterov
2012-09-13 15:52     ` Oleg Nesterov
2012-09-13 17:25       ` Roland McGrath
2012-09-17 10:39         ` Pedro Alves
2012-09-14 12:27     ` Denys Vlasenko
2012-09-14 16:38       ` Roland McGrath
2012-09-13 15:08 ` [PATCH 1/2] coredump: pass siginfo_t* to do_coredump() and below, not merely signr Oleg Nesterov
2012-09-13 14:31 [PATCH 2/2] coredump: add a new elf note with siginfo fields of the signal Jonathan M. Foote

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).