On Tue, May 15, 2018 at 04:05:33PM -0700, Linus Torvalds wrote:
> I wonder if there's some way to add a test for "ENTRY only works in a code
> section"?

I suppose we could add a discardable annotation to the ENTRY macro and
have objtool validate that it's in a text section.  I'm not sure whether
it's worth it, but I could do it if you think it's a good idea.

Below is a tentative objtool patch which catches asm code falling
through to INT3 padding, though objtool is 64-bit only so there won't be
any 32-bit coverage.  It found zero hits on my config.  I'll clean it up
and submit it tomorrow-ish.

diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 8344dd2f310a..3ed8cec6e765 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -285,11 +285,9 @@ ENTRY(early_idt_handler_array)
        .endif
        pushq $i                # 72(%rsp) Vector number
        jmp early_idt_handler_common
-       UNWIND_HINT_IRET_REGS
        i = i + 1
        .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
        .endr
-       UNWIND_HINT_IRET_REGS offset=16
 END(early_idt_handler_array)
 
 early_idt_handler_common:
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index b0d7dc3d71b5..6eb058a8ac00 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -33,7 +33,8 @@
 #define INSN_STACK             8
 #define INSN_BUG               9
 #define INSN_NOP               10
-#define INSN_OTHER             11
+#define INSN_PADDING           11
+#define INSN_OTHER             12
 #define INSN_LAST              INSN_OTHER
 
 enum op_dest_type {
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 7e86a743f851..82b41bb93c02 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -421,7 +421,7 @@ int arch_decode_instruction(struct elf *elf, struct section 
*sec,
 
        case 0xcc:
                /* int3: used for asm function padding by the __ALIGN macro */
-               *type = INSN_NOP;
+               *type = INSN_PADDING;
                break;
 
        case 0xe3:
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f4bbce838433..8a83a0d1693a 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1936,6 +1936,14 @@ static int validate_branch(struct objtool_file *file, 
struct instruction *first,
                        }
                        return 0;
 
+               case INSN_PADDING:
+                       if (!func) {
+                               WARN_FUNC("code falls through to INT3 padding",
+                                         insn->sec, insn->offset);
+                               return 1;
+                       }
+                       break;
+
                case INSN_STACK:
                        if (update_insn_state(insn, &state))
                                return 1;
@@ -2032,7 +2040,8 @@ static bool ignore_unreachable_insn(struct instruction 
*insn)
 {
        int i;
 
-       if (insn->ignore || insn->type == INSN_NOP)
+       if (insn->ignore || insn->type == INSN_NOP ||
+           insn->type == INSN_PADDING)
                return true;
 
        /*

Reply via email to