Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Handle Clang RSP musical chairs

For no apparent reason (possibly related to CONFIG_KMSAN), Clang can
randomly pass the value of RSP to other registers and then back again to
RSP. Handle that accordingly.

Fixes the following warnings:

drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: undefined stack state
drivers/input/misc/uinput.o: warning: objtool: uinput_str_to_user+0x165: unknown CFA base reg -1

Reported-by: Arnd Bergmann <arnd@arndb.de>
Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com
Link: https://patch.msgid.link/240e6a172cc73292499334a3724d02ccb3247fc7.1772818491.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+40 -42
+26 -42
tools/objtool/arch/x86/decode.c
··· 395 395 if (!rex_w) 396 396 break; 397 397 398 - if (modrm_reg == CFI_SP) { 399 - 400 - if (mod_is_reg()) { 401 - /* mov %rsp, reg */ 402 - ADD_OP(op) { 403 - op->src.type = OP_SRC_REG; 404 - op->src.reg = CFI_SP; 405 - op->dest.type = OP_DEST_REG; 406 - op->dest.reg = modrm_rm; 407 - } 408 - break; 409 - 410 - } else { 411 - /* skip RIP relative displacement */ 412 - if (is_RIP()) 413 - break; 414 - 415 - /* skip nontrivial SIB */ 416 - if (have_SIB()) { 417 - modrm_rm = sib_base; 418 - if (sib_index != CFI_SP) 419 - break; 420 - } 421 - 422 - /* mov %rsp, disp(%reg) */ 423 - ADD_OP(op) { 424 - op->src.type = OP_SRC_REG; 425 - op->src.reg = CFI_SP; 426 - op->dest.type = OP_DEST_REG_INDIRECT; 427 - op->dest.reg = modrm_rm; 428 - op->dest.offset = ins.displacement.value; 429 - } 430 - break; 431 - } 432 - 433 - break; 434 - } 435 - 436 - if (rm_is_reg(CFI_SP)) { 437 - 438 - /* mov reg, %rsp */ 398 + if (mod_is_reg()) { 399 + /* mov reg, reg */ 439 400 ADD_OP(op) { 440 401 op->src.type = OP_SRC_REG; 441 402 op->src.reg = modrm_reg; 442 403 op->dest.type = OP_DEST_REG; 443 - op->dest.reg = CFI_SP; 404 + op->dest.reg = modrm_rm; 405 + } 406 + break; 407 + } 408 + 409 + /* skip RIP relative displacement */ 410 + if (is_RIP()) 411 + break; 412 + 413 + /* skip nontrivial SIB */ 414 + if (have_SIB()) { 415 + modrm_rm = sib_base; 416 + if (sib_index != CFI_SP) 417 + break; 418 + } 419 + 420 + /* mov %rsp, disp(%reg) */ 421 + if (modrm_reg == CFI_SP) { 422 + ADD_OP(op) { 423 + op->src.type = OP_SRC_REG; 424 + op->src.reg = CFI_SP; 425 + op->dest.type = OP_DEST_REG_INDIRECT; 426 + op->dest.reg = modrm_rm; 427 + op->dest.offset = ins.displacement.value; 444 428 } 445 429 break; 446 430 }
+14
tools/objtool/check.c
··· 3000 3000 cfi->stack_size += 8; 3001 3001 } 3002 3002 3003 + else if (cfi->vals[op->src.reg].base == CFI_CFA) { 3004 + /* 3005 + * Clang RSP musical chairs: 3006 + * 3007 + * mov %rsp, %rdx [handled above] 3008 + * ... 3009 + * mov %rdx, %rbx [handled here] 3010 + * ... 3011 + * mov %rbx, %rsp [handled above] 3012 + */ 3013 + cfi->vals[op->dest.reg].base = CFI_CFA; 3014 + cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; 3015 + } 3016 + 3003 3017 3004 3018 break; 3005 3019