[PATCH] "graph" segfaults on top-level asm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The "graph" binary segfaults on this input:
	asm("");
with gdb saying (edited for clarity):
	Program received signal SIGSEGV, Segmentation fault.
		in graph_ep (ep=0x7ffff7f62010) at graph.c:52
	(gdb) p ep->entry
	$1 = (struct instruction *) 0x0

Sadly, the commit that introduced this crash:
	15fa4d60e ("topasm: top-level asm is special")
was (part of a bigger series) meant to fix crashes because
of such toplevel asm statements.

Fix this by partially reversing this commit, adding a few
checks in some others places (for tools not using the entrypoint)
and disabling output in test-parsing.c

Fixes: 15fa4d60ebba3025495bb34f0718764336d3dfe0
Reported-by: Vegard Nossum <vegard.nossum@xxxxxxxxx>
Analyzed-by: Vegard Nossum <vegard.nossum@xxxxxxxxx>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 dissect.c      | 2 ++
 graph.c        | 2 ++
 linearize.c    | 8 ++++----
 sparse-llvm.c  | 3 +++
 test-inspect.c | 2 ++
 test-parsing.c | 4 +++-
 6 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/dissect.c b/dissect.c
index 14d57bf5b..70d67ccbd 100644
--- a/dissect.c
+++ b/dissect.c
@@ -575,6 +575,8 @@ static inline struct symbol *do_symbol(struct symbol *sym)
 
 	type = base_type(sym);
 
+	if (!sym->ident)		// toplevel asm
+		return type;
 	if (reporter->r_symdef)
 		reporter->r_symdef(sym);
 
diff --git a/graph.c b/graph.c
index be4cf282c..d8a276e11 100644
--- a/graph.c
+++ b/graph.c
@@ -182,6 +182,8 @@ int main(int argc, char **argv)
 		concat_symbol_list(fsyms, &all_syms);
 
 		FOR_EACH_PTR(fsyms, sym) {
+			if (!sym->ident) // toplevel asm
+				continue;
 			expand_symbol(sym);
 			linearize_symbol(sym);
 		} END_FOR_EACH_PTR(sym);
diff --git a/linearize.c b/linearize.c
index 30ed2a302..3d21bafab 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2471,15 +2471,15 @@ static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_t
 	bb = alloc_basic_block(ep, sym->pos);
 	set_activeblock(ep, bb);
 
+	entry = alloc_instruction(OP_ENTRY, 0);
+	add_one_insn(ep, entry);
+	ep->entry = entry;
+
 	if (stmt->type == STMT_ASM) {	// top-level asm
 		linearize_asm_statement(ep, stmt);
 		return ep;
 	}
 
-	entry = alloc_instruction(OP_ENTRY, 0);
-	add_one_insn(ep, entry);
-	ep->entry = entry;
-
 	concat_symbol_list(base_type->arguments, &ep->syms);
 
 	/* FIXME!! We should do something else about varargs.. */
diff --git a/sparse-llvm.c b/sparse-llvm.c
index c7a9fbb7e..69da8d4e8 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1139,6 +1139,9 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	int nr_args = 0;
 	int i;
 
+	if (!sym->ident)		// toplevel asm
+		return;
+
 	function.fn = get_sym_value(module, sym);
 	LLVMSetFunctionCallConv(function.fn, LLVMCCallConv);
 	LLVMSetLinkage(function.fn, function_linkage(sym));
diff --git a/test-inspect.c b/test-inspect.c
index 63754cb3c..d9bbebf0e 100644
--- a/test-inspect.c
+++ b/test-inspect.c
@@ -20,6 +20,8 @@ static void expand_symbols(struct symbol_list *list)
 {
 	struct symbol *sym;
 	FOR_EACH_PTR(list, sym) {
+		if (!sym->ident)	// toplevel asm
+			continue;
 		expand_symbol(sym);
 	} END_FOR_EACH_PTR(sym);
 }
diff --git a/test-parsing.c b/test-parsing.c
index c5bc42e19..d18342f5f 100644
--- a/test-parsing.c
+++ b/test-parsing.c
@@ -44,6 +44,8 @@ static void clean_up_symbols(struct symbol_list *list)
 	struct symbol *sym;
 
 	FOR_EACH_PTR(list, sym) {
+		if (!sym->ident)	// toplevel asm
+			continue;
 		expand_symbol(sym);
 	} END_FOR_EACH_PTR(sym);
 }
@@ -70,7 +72,7 @@ int main(int argc, char **argv)
 		// Simplification
 		clean_up_symbols(list);
 
-#if 1
+#if 0
 		// Show the end result.
 		show_symbol_list(list, "\n\n");
 		printf("\n\n");
-- 
2.23.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux