Commit ed4fe7f4 authored by Matt Fleming's avatar Matt Fleming

sh: Fix memory leak in dwarf_unwind_stack()

If we broke out of the while (1) loop because the return address of
"frame" was zero, then "frame" needs to be free'd before we return.
Signed-off-by: default avatarMatt Fleming <matt@console-pimps.org>
parent a6a2f2ad
...@@ -376,6 +376,7 @@ static inline unsigned int DW_CFA_operand(unsigned long insn) ...@@ -376,6 +376,7 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
struct dwarf_frame *); struct dwarf_frame *);
extern void dwarf_free_frame(struct dwarf_frame *);
extern int dwarf_parse_section(char *, char *, struct module *); extern int dwarf_parse_section(char *, char *, struct module *);
extern void dwarf_module_unload(struct module *); extern void dwarf_module_unload(struct module *);
......
...@@ -529,6 +529,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, ...@@ -529,6 +529,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
return 0; return 0;
} }
/**
* dwarf_free_frame - free the memory allocated for @frame
* @frame: the frame to free
*/
void dwarf_free_frame(struct dwarf_frame *frame)
{
dwarf_frame_free_regs(frame);
mempool_free(frame, dwarf_frame_pool);
}
/** /**
* dwarf_unwind_stack - recursively unwind the stack * dwarf_unwind_stack - recursively unwind the stack
* @pc: address of the function to unwind * @pc: address of the function to unwind
...@@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, ...@@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
return frame; return frame;
bail: bail:
dwarf_frame_free_regs(frame); dwarf_free_frame(frame);
mempool_free(frame, dwarf_frame_pool);
return NULL; return NULL;
} }
...@@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task, ...@@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task,
while (1) { while (1) {
frame = dwarf_unwind_stack(return_addr, _frame); frame = dwarf_unwind_stack(return_addr, _frame);
if (_frame) { if (_frame)
dwarf_frame_free_regs(_frame); dwarf_free_frame(_frame);
mempool_free(_frame, dwarf_frame_pool);
}
_frame = frame; _frame = frame;
...@@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task, ...@@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task,
return_addr = frame->return_addr; return_addr = frame->return_addr;
ops->address(data, return_addr, 1); ops->address(data, return_addr, 1);
} }
if (frame)
dwarf_free_frame(frame);
} }
static struct unwinder dwarf_unwinder = { static struct unwinder dwarf_unwinder = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment