forked from mirrors/linux
		
	x86/traps: Decode 0xEA instructions as #UD
FineIBT will start using 0xEA as #UD. Normally '0xEA' is a 'bad', invalid instruction for the CPU. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Kees Cook <kees@kernel.org> Link: https://lore.kernel.org/r/20250224124200.166774696@infradead.org
This commit is contained in:
		
							parent
							
								
									5d703825fd
								
							
						
					
					
						commit
						2e044911be
					
				
					 2 changed files with 18 additions and 3 deletions
				
			
		|  | @ -25,6 +25,7 @@ | ||||||
| #define BUG_UD2			0xfffe | #define BUG_UD2			0xfffe | ||||||
| #define BUG_UD1			0xfffd | #define BUG_UD1			0xfffd | ||||||
| #define BUG_UD1_UBSAN		0xfffc | #define BUG_UD1_UBSAN		0xfffc | ||||||
|  | #define BUG_EA			0xffea | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_GENERIC_BUG | #ifdef CONFIG_GENERIC_BUG | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -96,6 +96,7 @@ __always_inline int is_valid_bugaddr(unsigned long addr) | ||||||
|  * Check for UD1 or UD2, accounting for Address Size Override Prefixes. |  * Check for UD1 or UD2, accounting for Address Size Override Prefixes. | ||||||
|  * If it's a UD1, further decode to determine its use: |  * If it's a UD1, further decode to determine its use: | ||||||
|  * |  * | ||||||
|  |  * FineIBT:      ea                      (bad) | ||||||
|  * UBSan{0}:     67 0f b9 00             ud1    (%eax),%eax |  * UBSan{0}:     67 0f b9 00             ud1    (%eax),%eax | ||||||
|  * UBSan{10}:    67 0f b9 40 10          ud1    0x10(%eax),%eax |  * UBSan{10}:    67 0f b9 40 10          ud1    0x10(%eax),%eax | ||||||
|  * static_call:  0f b9 cc                ud1    %esp,%ecx |  * static_call:  0f b9 cc                ud1    %esp,%ecx | ||||||
|  | @ -113,6 +114,10 @@ __always_inline int decode_bug(unsigned long addr, s32 *imm, int *len) | ||||||
| 	v = *(u8 *)(addr++); | 	v = *(u8 *)(addr++); | ||||||
| 	if (v == INSN_ASOP) | 	if (v == INSN_ASOP) | ||||||
| 		v = *(u8 *)(addr++); | 		v = *(u8 *)(addr++); | ||||||
|  | 	if (v == 0xea) { | ||||||
|  | 		*len = addr - start; | ||||||
|  | 		return BUG_EA; | ||||||
|  | 	} | ||||||
| 	if (v != OPCODE_ESCAPE) | 	if (v != OPCODE_ESCAPE) | ||||||
| 		return BUG_NONE; | 		return BUG_NONE; | ||||||
| 
 | 
 | ||||||
|  | @ -309,10 +314,16 @@ static noinstr bool handle_bug(struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	switch (ud_type) { | 	switch (ud_type) { | ||||||
| 	case BUG_UD2: | 	case BUG_UD2: | ||||||
| 		if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN || | 		if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) { | ||||||
| 		    handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) { |  | ||||||
| 			regs->ip += ud_len; |  | ||||||
| 			handled = true; | 			handled = true; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		fallthrough; | ||||||
|  | 
 | ||||||
|  | 	case BUG_EA: | ||||||
|  | 		if (handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) { | ||||||
|  | 			handled = true; | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
|  | @ -328,6 +339,9 @@ static noinstr bool handle_bug(struct pt_regs *regs) | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (handled) | ||||||
|  | 		regs->ip += ud_len; | ||||||
|  | 
 | ||||||
| 	if (regs->flags & X86_EFLAGS_IF) | 	if (regs->flags & X86_EFLAGS_IF) | ||||||
| 		raw_local_irq_disable(); | 		raw_local_irq_disable(); | ||||||
| 	instrumentation_end(); | 	instrumentation_end(); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Peter Zijlstra
						Peter Zijlstra