Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed4fe7f4 authored by Matt Fleming's avatar Matt Fleming
Browse files

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -376,6 +376,7 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)

extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
					      struct dwarf_frame *);
extern void dwarf_free_frame(struct dwarf_frame *);
extern int dwarf_parse_section(char *, char *, struct module *);
extern void dwarf_module_unload(struct module *);

+16 −6
Original line number Diff line number Diff line
@@ -529,6 +529,16 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
	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
 *	@pc: address of the function to unwind
@@ -649,8 +659,7 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
	return frame;

bail:
	dwarf_frame_free_regs(frame);
	mempool_free(frame, dwarf_frame_pool);
	dwarf_free_frame(frame);
	return NULL;
}

@@ -837,10 +846,8 @@ static void dwarf_unwinder_dump(struct task_struct *task,
	while (1) {
		frame = dwarf_unwind_stack(return_addr, _frame);

		if (_frame) {
			dwarf_frame_free_regs(_frame);
			mempool_free(_frame, dwarf_frame_pool);
		}
		if (_frame)
			dwarf_free_frame(_frame);

		_frame = frame;

@@ -850,6 +857,9 @@ static void dwarf_unwinder_dump(struct task_struct *task,
		return_addr = frame->return_addr;
		ops->address(data, return_addr, 1);
	}

	if (frame)
		dwarf_free_frame(frame);
}

static struct unwinder dwarf_unwinder = {