On Mon, Feb 25, 2019 at 12:47:00AM -0800, h...@zytor.com wrote:
> It doesn't have to understand the contents of the memop, but it seems
> that the presence of a modrm with mode ≠ 3 should be plenty. It needs
> to know that much in order to know the length of instructions anyway.
> For extra credit, ignore LEA or hinting instructions.

A little something like so then?

arch/x86/kernel/fpu/signal.o: warning: objtool: .altinstr_replacement+0x9c: 
UACCESS disable without MEMOPs: copy_fpstate_to_sigframe()

00000000023c  000200000002 R_X86_64_PC32     0000000000000000 .text + 604
000000000240  000700000002 R_X86_64_PC32     0000000000000000 
.altinstr_replacement + 99
000000000249  000200000002 R_X86_64_PC32     0000000000000000 .text + 610
00000000024d  000700000002 R_X86_64_PC32     0000000000000000 
.altinstr_replacement + 9c

.text

604:   90                      nop
605:   90                      nop
606:   90                      nop
607:   83 ce 03                or     $0x3,%esi
60a:   89 b3 00 02 00 00       mov    %esi,0x200(%rbx)
610:   90                      nop
611:   90                      nop
612:   90                      nop

.altinstr_replacement

99:   0f 01 cb                stac
9c:   0f 01 ca                clac

Which looks like the tool failed to recognise that MOV as a memop.



---
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -37,7 +37,8 @@
 #define INSN_CLAC              12
 #define INSN_STD               13
 #define INSN_CLD               14
-#define INSN_OTHER             15
+#define INSN_MEMOP             15
+#define INSN_OTHER             16
 #define INSN_LAST              INSN_OTHER
 
 enum op_dest_type {
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -123,6 +123,9 @@ int arch_decode_instruction(struct elf *
                modrm_mod = X86_MODRM_MOD(modrm);
                modrm_reg = X86_MODRM_REG(modrm);
                modrm_rm = X86_MODRM_RM(modrm);
+
+               if (modrm_mod != 3)
+                       *type = INSN_MEMOP;
        }
 
        if (insn.sib.nbytes)
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2047,6 +2047,7 @@ static int validate_branch(struct objtoo
                                WARN_FUNC("recursive UACCESS enable", sec, 
insn->offset);
 
                        state.uaccess = true;
+                       state.memop = false;
                        break;
 
                case INSN_CLAC:
@@ -2058,6 +2059,9 @@ static int validate_branch(struct objtoo
                                break;
                        }
 
+                       if (!state.memop && insn->func)
+                               WARN_FUNC("UACCESS disable without MEMOPs: 
%s()", sec, insn->offset, insn->func->name);
+
                        state.uaccess = false;
                        break;
 
@@ -2075,6 +2079,10 @@ static int validate_branch(struct objtoo
                        state.df = false;
                        break;
 
+               case INSN_MEMOP:
+                       state.memop = true;
+                       break;
+
                default:
                        break;
                }
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -31,7 +31,7 @@ struct insn_state {
        int stack_size;
        unsigned char type;
        bool bp_scratch;
-       bool drap, end, uaccess, uaccess_safe, df;
+       bool drap, end, uaccess, uaccess_safe, df, memop;
        int drap_reg, drap_offset;
        struct cfi_reg vals[CFI_NUM_REGS];
 };

Reply via email to