Re: [PATCH 1/2] x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK

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

 



On Wed, Sep 07, 2022 at 10:02:41AM +0200, Peter Zijlstra wrote:
> Maybe something like:
> 
> struct queue {
> 	int head, tail;
> 	unsigned long val[16]; /* insufficient; probably should allocate something */
> };
> 
> void push(struct queue *q, unsigned long val)
> {
> 	/* break loops, been here already */
> 	for (int i = 0; i < q->head; i++) {
> 		if (q->val[i] == val)
> 			return;
> 	}
> 
> 	q->val[q->head++] = val;
> 
> 	WARN_ON(q->head > ARRAY_SIZE(q->val)
> }
> 
> unsigned long pop(struct queue *q)
> {
> 	if (q->tail == q->head)
> 		return 0;
> 
> 	return q->val[q->tail++];
> }
> 
> bool dead_end_insn(struct instruction *insn)
> {
> 	switch (insn->opcode.bytes[0]) {
> 	case INT3_INSN_OPCODE:
> 	case JMP8_INSN_OPCODE:
> 	case JMP32_INSN_OPCODE:

	case RET_INSN_OPCODE:

> 		return true; /* no arch execution after these */
> 
> 	case 0xff:
> 		/* jmp *%reg; jmpf */
> 		if (modrm_reg == 4 || modrm_reg == 5)
> 			return true;
> 		break;
> 
> 	default:
> 		break;
> 	}
> 
> 	return false;
> }
> 
> 
> 
> 	struct queue q;
> 
> 	start = paddr - offset;
> 	end = start + size;
> 	push(&q, paddr - offset);
> 
> 	while (start = pop(&q)) {
> 		for_each_insn(&insn, start, end, buf) {
> 			if (insn.kaddr == paddr)
> 				return 1;
> 
> 			target = insn_get_branch_addr(&insn);
> 			if (target)
> 				push(&q, target);
> 
> 			if (dead_end_insn(&insn))
> 				break;
> 		}
> 	}
> 
> 
> 
> It's a bit of a pain, but I think it should cover things.



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux