diff mbox series

[bpf,1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block

Message ID 164915122721.982637.1510683757540074397.stgit@devnote2 (mailing list archive)
State New, archived
Headers show
Series kprobes: rethook, ARM, arm64: Replace kretprobe trampoline with rethook | expand

Commit Message

Masami Hiramatsu (Google) April 5, 2022, 9:33 a.m. UTC
Since the unwind_ctrl_block::lr_addr is finally passed to
stackframe::lr_addr, that value will be exposed unconditionally.
Thus it should be initialized.

Without this fix, when unwind_frame() doesn't update the
unwind_ctrl_block::lr_addr (e.g. 'lr' register is not saved in the
target function), stackframe::lr_addr will contain a wrong value.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 arch/arm/kernel/unwind.c |    1 +
 1 file changed, 1 insertion(+)

Comments

kernel test robot April 6, 2022, 6:53 p.m. UTC | #1
Hi Masami,

I love your patch! Perhaps something to improve:

[auto build test WARNING on bpf/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master
config: arm-randconfig-s032-20220406 (https://download.01.org/0day-ci/archive/20220407/202204070204.g3wpjuJi-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/intel-lab-lkp/linux/commit/99971b0c57ce1501eda858656ed06758bbd4e376
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153
        git checkout 99971b0c57ce1501eda858656ed06758bbd4e376
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> arch/arm/kernel/unwind.c:407:24: sparse: sparse: Using plain integer as NULL pointer

vim +407 arch/arm/kernel/unwind.c

   377	
   378	/*
   379	 * Unwind a single frame starting with *sp for the symbol at *pc. It
   380	 * updates the *pc and *sp with the new values.
   381	 */
   382	int unwind_frame(struct stackframe *frame)
   383	{
   384		const struct unwind_idx *idx;
   385		struct unwind_ctrl_block ctrl;
   386		unsigned long sp_low;
   387	
   388		/* store the highest address on the stack to avoid crossing it*/
   389		sp_low = frame->sp;
   390		ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN)
   391			       + THREAD_SIZE;
   392	
   393		pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
   394			 frame->pc, frame->lr, frame->sp);
   395	
   396		idx = unwind_find_idx(frame->pc);
   397		if (!idx) {
   398			if (frame->pc && kernel_text_address(frame->pc))
   399				pr_warn("unwind: Index not found %08lx\n", frame->pc);
   400			return -URC_FAILURE;
   401		}
   402	
   403		ctrl.vrs[FP] = frame->fp;
   404		ctrl.vrs[SP] = frame->sp;
   405		ctrl.vrs[LR] = frame->lr;
   406		ctrl.vrs[PC] = 0;
 > 407		ctrl.lr_addr = 0;
   408	
   409		if (idx->insn == 1)
   410			/* can't unwind */
   411			return -URC_FAILURE;
   412		else if (frame->pc == prel31_to_addr(&idx->addr_offset)) {
   413			/*
   414			 * Unwinding is tricky when we're halfway through the prologue,
   415			 * since the stack frame that the unwinder expects may not be
   416			 * fully set up yet. However, one thing we do know for sure is
   417			 * that if we are unwinding from the very first instruction of
   418			 * a function, we are still effectively in the stack frame of
   419			 * the caller, and the unwind info has no relevance yet.
   420			 */
   421			if (frame->pc == frame->lr)
   422				return -URC_FAILURE;
   423			frame->pc = frame->lr;
   424			return URC_OK;
   425		} else if ((idx->insn & 0x80000000) == 0)
   426			/* prel31 to the unwind table */
   427			ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
   428		else if ((idx->insn & 0xff000000) == 0x80000000)
   429			/* only personality routine 0 supported in the index */
   430			ctrl.insn = &idx->insn;
   431		else {
   432			pr_warn("unwind: Unsupported personality routine %08lx in the index at %p\n",
   433				idx->insn, idx);
   434			return -URC_FAILURE;
   435		}
   436	
   437		/* check the personality routine */
   438		if ((*ctrl.insn & 0xff000000) == 0x80000000) {
   439			ctrl.byte = 2;
   440			ctrl.entries = 1;
   441		} else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
   442			ctrl.byte = 1;
   443			ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
   444		} else {
   445			pr_warn("unwind: Unsupported personality routine %08lx at %p\n",
   446				*ctrl.insn, ctrl.insn);
   447			return -URC_FAILURE;
   448		}
   449	
   450		ctrl.check_each_pop = 0;
   451	
   452		if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) {
   453			/*
   454			 * call_with_stack() is the only place where we permit SP to
   455			 * jump from one stack to another, and since we know it is
   456			 * guaranteed to happen, set up the SP bounds accordingly.
   457			 */
   458			sp_low = frame->fp;
   459			ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE);
   460		}
   461	
   462		while (ctrl.entries > 0) {
   463			int urc;
   464			if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
   465				ctrl.check_each_pop = 1;
   466			urc = unwind_exec_insn(&ctrl);
   467			if (urc < 0)
   468				return urc;
   469			if (ctrl.vrs[SP] < sp_low || ctrl.vrs[SP] > ctrl.sp_high)
   470				return -URC_FAILURE;
   471		}
   472	
   473		if (ctrl.vrs[PC] == 0)
   474			ctrl.vrs[PC] = ctrl.vrs[LR];
   475	
   476		/* check for infinite loop */
   477		if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP])
   478			return -URC_FAILURE;
   479	
   480		frame->fp = ctrl.vrs[FP];
   481		frame->sp = ctrl.vrs[SP];
   482		frame->lr = ctrl.vrs[LR];
   483		frame->pc = ctrl.vrs[PC];
   484		frame->lr_addr = ctrl.lr_addr;
   485	
   486		return URC_OK;
   487	}
   488
diff mbox series

Patch

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index a37ea6c772cd..93e767682cf4 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -404,6 +404,7 @@  int unwind_frame(struct stackframe *frame)
 	ctrl.vrs[SP] = frame->sp;
 	ctrl.vrs[LR] = frame->lr;
 	ctrl.vrs[PC] = 0;
+	ctrl.lr_addr = 0;
 
 	if (idx->insn == 1)
 		/* can't unwind */