public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
@ 2025-10-09 13:07 kernel test robot
  2025-10-10  3:20 ` Nathan Chancellor
  0 siblings, 1 reply; 10+ messages in thread
From: kernel test robot @ 2025-10-09 13:07 UTC (permalink / raw)
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
head:   6c6e6a5416471498d8aafc050110bec9467e4da7
commit: 6c6e6a5416471498d8aafc050110bec9467e4da7 [1/1] Merge branch 'linus' into x86/core, to resolve conflicts
config: x86_64-buildonly-randconfig-001-20251009 (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510092124.O2IX0Jek-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-09 13:07 [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call! kernel test robot
@ 2025-10-10  3:20 ` Nathan Chancellor
  2025-10-10  7:10   ` Peter Zijlstra
  0 siblings, 1 reply; 10+ messages in thread
From: Nathan Chancellor @ 2025-10-10  3:20 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

Hi Peter,

On Thu, Oct 09, 2025 at 09:07:02PM +0800, kernel test robot wrote:
> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
> head:   6c6e6a5416471498d8aafc050110bec9467e4da7
> commit: 6c6e6a5416471498d8aafc050110bec9467e4da7 [1/1] Merge branch 'linus' into x86/core, to resolve conflicts

It appears that this got bisected to the merge because the configuration
has CONFIG_CFI=y, which needs the rename that is in Linus's tree. This
is reproducible with just commit 894af4a1cde6 ("objtool: Validate kCFI
calls") cherry-picked onto 6.17 and CONFIG_CFI_CLANG=y in the config
provided at the link below.

> config: x86_64-buildonly-randconfig-001-20251009 (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/config)
> compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202510092124.O2IX0Jek-lkp@intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
> >> vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!

I do see an indirect call in rcar_pcie_probe() with ->host_init_fn() but
rcar_pcie_probe() is not __nocfi... +0x13e is 0x8d9d7e in this build.

    8d9d6f: 31 c0                         xorl    %eax, %eax
    8d9d71: 49 89 86 58 06 00 00          movq    %rax, 0x658(%r14)
    8d9d78: 4c 89 ff                      movq    %r15, %rdi
    8d9d7b: 45 31 db                      xorl    %r11d, %r11d
    8d9d7e: 2e e8 00 00 00 00             callq   0x8d9d84 <rcar_pcie_probe+0x144>
                  00000000008d9d80:  R_X86_64_PLT32       __x86_indirect_thunk_r11-0x4

Is this an issue with the objtool check or is clang not generating the
right code?

Cheers,
Nathan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-10  3:20 ` Nathan Chancellor
@ 2025-10-10  7:10   ` Peter Zijlstra
  2025-10-10  7:44     ` Peter Zijlstra
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Zijlstra @ 2025-10-10  7:10 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Thu, Oct 09, 2025 at 08:20:01PM -0700, Nathan Chancellor wrote:
> Hi Peter,
> 
> On Thu, Oct 09, 2025 at 09:07:02PM +0800, kernel test robot wrote:
> > tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
> > head:   6c6e6a5416471498d8aafc050110bec9467e4da7
> > commit: 6c6e6a5416471498d8aafc050110bec9467e4da7 [1/1] Merge branch 'linus' into x86/core, to resolve conflicts
> 
> It appears that this got bisected to the merge because the configuration
> has CONFIG_CFI=y, which needs the rename that is in Linus's tree. This
> is reproducible with just commit 894af4a1cde6 ("objtool: Validate kCFI
> calls") cherry-picked onto 6.17 and CONFIG_CFI_CLANG=y in the config
> provided at the link below.
> 
> > config: x86_64-buildonly-randconfig-001-20251009 (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/config)
> > compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/reproduce)
> > 
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202510092124.O2IX0Jek-lkp@intel.com/
> > 
> > All warnings (new ones prefixed by >>):
> > 
> > >> vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
> 
> I do see an indirect call in rcar_pcie_probe() with ->host_init_fn() but
> rcar_pcie_probe() is not __nocfi... +0x13e is 0x8d9d7e in this build.
> 
>     8d9d6f: 31 c0                         xorl    %eax, %eax
>     8d9d71: 49 89 86 58 06 00 00          movq    %rax, 0x658(%r14)
>     8d9d78: 4c 89 ff                      movq    %r15, %rdi
>     8d9d7b: 45 31 db                      xorl    %r11d, %r11d
>     8d9d7e: 2e e8 00 00 00 00             callq   0x8d9d84 <rcar_pcie_probe+0x144>
>                   00000000008d9d80:  R_X86_64_PLT32       __x86_indirect_thunk_r11-0x4
> 
> Is this an issue with the objtool check or is clang not generating the
> right code?

So going by the asm above, objtool is right, this is not a CFI adorned
indirect call.

Let me go build this thing.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-10  7:10   ` Peter Zijlstra
@ 2025-10-10  7:44     ` Peter Zijlstra
  2025-10-10 22:30       ` Nathan Chancellor
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Zijlstra @ 2025-10-10  7:44 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Fri, Oct 10, 2025 at 09:10:32AM +0200, Peter Zijlstra wrote:
> On Thu, Oct 09, 2025 at 08:20:01PM -0700, Nathan Chancellor wrote:
> > Hi Peter,
> > 
> > On Thu, Oct 09, 2025 at 09:07:02PM +0800, kernel test robot wrote:
> > > tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
> > > head:   6c6e6a5416471498d8aafc050110bec9467e4da7
> > > commit: 6c6e6a5416471498d8aafc050110bec9467e4da7 [1/1] Merge branch 'linus' into x86/core, to resolve conflicts
> > 
> > It appears that this got bisected to the merge because the configuration
> > has CONFIG_CFI=y, which needs the rename that is in Linus's tree. This
> > is reproducible with just commit 894af4a1cde6 ("objtool: Validate kCFI
> > calls") cherry-picked onto 6.17 and CONFIG_CFI_CLANG=y in the config
> > provided at the link below.
> > 
> > > config: x86_64-buildonly-randconfig-001-20251009 (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/config)
> > > compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
> > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251009/202510092124.O2IX0Jek-lkp@intel.com/reproduce)
> > > 
> > > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > > the same patch/commit), kindly add following tags
> > > | Reported-by: kernel test robot <lkp@intel.com>
> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202510092124.O2IX0Jek-lkp@intel.com/
> > > 
> > > All warnings (new ones prefixed by >>):
> > > 
> > > >> vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
> > 
> > I do see an indirect call in rcar_pcie_probe() with ->host_init_fn() but
> > rcar_pcie_probe() is not __nocfi... +0x13e is 0x8d9d7e in this build.
> > 
> >     8d9d6f: 31 c0                         xorl    %eax, %eax
> >     8d9d71: 49 89 86 58 06 00 00          movq    %rax, 0x658(%r14)
> >     8d9d78: 4c 89 ff                      movq    %r15, %rdi
> >     8d9d7b: 45 31 db                      xorl    %r11d, %r11d
> >     8d9d7e: 2e e8 00 00 00 00             callq   0x8d9d84 <rcar_pcie_probe+0x144>
> >                   00000000008d9d80:  R_X86_64_PLT32       __x86_indirect_thunk_r11-0x4
> > 
> > Is this an issue with the objtool check or is clang not generating the
> > right code?
> 
> So going by the asm above, objtool is right, this is not a CFI adorned
> indirect call.
> 
> Let me go build this thing.

vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!

$ ./scripts/objdump-func tmp-build/vmlinux.o rcar_pcie_probe
0000 00000000008c7a20 <rcar_pcie_probe>:
0000   8c7a20:  f3 0f 1e fa             endbr64
0004   8c7a24:  0f 1f 44 00 00          nopl   0x0(%rax,%rax,1) 8c7a25: R_X86_64_NONE   __fentry__-0x4
0009   8c7a29:  55                      push   %rbp
000a   8c7a2a:  41 57                   push   %r15
000c   8c7a2c:  41 56                   push   %r14
000e   8c7a2e:  41 55                   push   %r13
0010   8c7a30:  41 54                   push   %r12
0012   8c7a32:  53                      push   %rbx
0013   8c7a33:  49 89 fc                mov    %rdi,%r12
0016   8c7a36:  48 8d 5f 10             lea    0x10(%rdi),%rbx
001a   8c7a3a:  be 20 01 00 00          mov    $0x120,%esi
001f   8c7a3f:  48 89 df                mov    %rbx,%rdi
0022   8c7a42:  e8 00 00 00 00          call   8c7a47 <rcar_pcie_probe+0x27>    8c7a43: R_X86_64_PLT32  devm_pci_alloc_host_bridge-0x4
0027   8c7a47:  48 85 c0                test   %rax,%rax
002a   8c7a4a:  0f 84 74 01 00 00       je     8c7bc4 <rcar_pcie_probe+0x1a4>
0030   8c7a50:  49 89 c6                mov    %rax,%r14
0033   8c7a53:  4c 8d b8 40 05 00 00    lea    0x540(%rax),%r15
003a   8c7a5a:  4c 89 ff                mov    %r15,%rdi
003d   8c7a5d:  e8 00 00 00 00          call   8c7a62 <rcar_pcie_probe+0x42>    8c7a5e: R_X86_64_PLT32  __tsan_write8-0x4
0042   8c7a62:  49 89 9e 40 05 00 00    mov    %rbx,0x540(%r14)
0049   8c7a69:  49 8d bc 24 88 00 00 00         lea    0x88(%r12),%rdi
0051   8c7a71:  e8 00 00 00 00          call   8c7a76 <rcar_pcie_probe+0x56>    8c7a72: R_X86_64_PLT32  __tsan_write8-0x4
0056   8c7a76:  4d 89 bc 24 88 00 00 00         mov    %r15,0x88(%r12)
005e   8c7a7e:  45 31 ed                xor    %r13d,%r13d
0061   8c7a81:  4d 8b a5 00 00 00 00    mov    0x0(%r13),%r12   8c7a84: R_X86_64_32S    .rodata+0x587390
0068   8c7a88:  48 89 df                mov    %rbx,%rdi
006b   8c7a8b:  4c 89 e6                mov    %r12,%rsi
006e   8c7a8e:  e8 00 00 00 00          call   8c7a93 <rcar_pcie_probe+0x73>    8c7a8f: R_X86_64_PLT32  devm_regulator_get_enable_optional-0x4
0073   8c7a93:  85 c0                   test   %eax,%eax
0075   8c7a95:  0f 99 c1                setns  %cl
0078   8c7a98:  83 f8 ed                cmp    $0xffffffed,%eax
007b   8c7a9b:  0f 94 c2                sete   %dl
007e   8c7a9e:  08 ca                   or     %cl,%dl
0080   8c7aa0:  0f 84 25 01 00 00       je     8c7bcb <rcar_pcie_probe+0x1ab>
0086   8c7aa6:  49 83 c5 08             add    $0x8,%r13
008a   8c7aaa:  49 83 fd 18             cmp    $0x18,%r13
008e   8c7aae:  75 d1                   jne    8c7a81 <rcar_pcie_probe+0x61>
0090   8c7ab0:  4c 89 ff                mov    %r15,%rdi
0093   8c7ab3:  e8 00 00 00 00          call   8c7ab8 <rcar_pcie_probe+0x98>    8c7ab4: R_X86_64_PLT32  __tsan_read8-0x4
0098   8c7ab8:  49 8b 3f                mov    (%r15),%rdi
009b   8c7abb:  e8 00 00 00 00          call   8c7ac0 <rcar_pcie_probe+0xa0>    8c7abc: R_X86_64_PLT32  pm_runtime_enable-0x4
00a0   8c7ac0:  4c 89 ff                mov    %r15,%rdi
00a3   8c7ac3:  e8 00 00 00 00          call   8c7ac8 <rcar_pcie_probe+0xa8>    8c7ac4: R_X86_64_PLT32  __tsan_read8-0x4
00a8   8c7ac8:  49 8b 3f                mov    (%r15),%rdi
00ab   8c7acb:  be 04 00 00 00          mov    $0x4,%esi
00b0   8c7ad0:  e8 00 00 00 00          call   8c7ad5 <rcar_pcie_probe+0xb5>    8c7ad1: R_X86_64_PLT32  __pm_runtime_resume-0x4
00b5   8c7ad5:  89 c5                   mov    %eax,%ebp
00b7   8c7ad7:  4c 89 ff                mov    %r15,%rdi
00ba   8c7ada:  e8 00 00 00 00          call   8c7adf <rcar_pcie_probe+0xbf>    8c7adb: R_X86_64_PLT32  __tsan_read8-0x4
00bf   8c7adf:  49 8b 3f                mov    (%r15),%rdi
00c2   8c7ae2:  85 ed                   test   %ebp,%ebp
00c4   8c7ae4:  0f 88 09 01 00 00       js     8c7bf3 <rcar_pcie_probe+0x1d3>
00ca   8c7aea:  48 c7 c6 00 00 00 00    mov    $0x0,%rsi        8c7aed: R_X86_64_32S    .rodata.str1.1+0x101fe2
00d1   8c7af1:  e8 00 00 00 00          call   8c7af6 <rcar_pcie_probe+0xd6>    8c7af2: R_X86_64_PLT32  devm_phy_optional_get-0x4
00d6   8c7af6:  49 89 c4                mov    %rax,%r12
00d9   8c7af9:  49 8d be 50 05 00 00    lea    0x550(%r14),%rdi
00e0   8c7b00:  e8 00 00 00 00          call   8c7b05 <rcar_pcie_probe+0xe5>    8c7b01: R_X86_64_PLT32  __tsan_write8-0x4
00e5   8c7b05:  4d 89 a6 50 05 00 00    mov    %r12,0x550(%r14)
00ec   8c7b0c:  49 81 fc 01 f0 ff ff    cmp    $0xfffffffffffff001,%r12
00f3   8c7b13:  bd ea ff ff ff          mov    $0xffffffea,%ebp
00f8   8c7b18:  41 0f 43 ec             cmovae %r12d,%ebp
00fc   8c7b1c:  85 ed                   test   %ebp,%ebp
00fe   8c7b1e:  0f 88 dd 00 00 00       js     8c7c01 <rcar_pcie_probe+0x1e1>
0104   8c7b24:  48 c7 c7 00 00 00 00    mov    $0x0,%rdi        8c7b27: R_X86_64_32S    .rodata.str1.1+0x132d1d
010b   8c7b2b:  be 4a 01 00 00          mov    $0x14a,%esi
0110   8c7b30:  e8 00 00 00 00          call   8c7b35 <rcar_pcie_probe+0x115>   8c7b31: R_X86_64_PLT32  __might_sleep-0x4
0115   8c7b35:  4c 89 ff                mov    %r15,%rdi
0118   8c7b38:  e8 ee 00 00 00          call   8c7c2b <rcar_pcie_parse_map_dma_ranges>
011d   8c7b3d:  89 c5                   mov    %eax,%ebp
011f   8c7b3f:  85 c0                   test   %eax,%eax
0121   8c7b41:  75 21                   jne    8c7b64 <rcar_pcie_probe+0x144>
0123   8c7b43:  49 8d be 58 06 00 00    lea    0x658(%r14),%rdi
012a   8c7b4a:  e8 00 00 00 00          call   8c7b4f <rcar_pcie_probe+0x12f>   8c7b4b: R_X86_64_PLT32  __tsan_write8-0x4
012f   8c7b4f:  31 c0                   xor    %eax,%eax
0131   8c7b51:  49 89 86 58 06 00 00    mov    %rax,0x658(%r14)
0138   8c7b58:  4c 89 ff                mov    %r15,%rdi
013b   8c7b5b:  45 31 db                xor    %r11d,%r11d
013e   8c7b5e:  2e e8 00 00 00 00       cs call 8c7b64 <rcar_pcie_probe+0x144>  8c7b60: R_X86_64_PLT32  __x86_indirect_thunk_r11-0x4

That's here... and that is indeed broken. Also note how it zeros r11
right before calling it.

AFAICT this is:

        host->phy_init_fn = of_device_get_match_data(dev);
        err = host->phy_init_fn(host);

Where it has decided that of_device_get_match_data() *will* return NULL
and then helpfully emits (*NULL)(); or something like that. And then
forgets to add CFI bits on for extra fun and games.



Anyway, look at the output of:

$ objdump -wdr defconfig-build/vmlinux.o | grep -C 10 __x86_indirect_thunk_r11

      57:       41 ba 40 2f 74 0e       mov    $0xe742f40,%r10d
      5d:       45 03 53 f1             add    -0xf(%r11),%r10d
      61:       74 02                   je     65 <__traceiter_initcall_level+0x55>
      63:       0f 0b                   ud2
      65:       2e e8 00 00 00 00       cs call 6b <__traceiter_initcall_level+0x5b>    67: R_X86_64_PLT32      __x86_indirect_thunk_r11-0x4

     107:       41 ba f6 c0 b9 f6       mov    $0xf6b9c0f6,%r10d
     10d:       45 03 53 f1             add    -0xf(%r11),%r10d
     111:       74 02                   je     115 <__traceiter_initcall_start+0x55>
     113:       0f 0b                   ud2
     115:       2e e8 00 00 00 00       cs call 11b <__traceiter_initcall_start+0x5b>   117: R_X86_64_PLT32     __x86_indirect_thunk_r11-0x4

     1bd:       41 ba cc ca 37 0d       mov    $0xd37cacc,%r10d
     1c3:       45 03 53 f1             add    -0xf(%r11),%r10d
     1c7:       74 02                   je     1cb <__traceiter_initcall_finish+0x5b>
     1c9:       0f 0b                   ud2
     1cb:       2e e8 00 00 00 00       cs call 1d1 <__traceiter_initcall_finish+0x61>  1cd: R_X86_64_PLT32     __x86_indirect_thunk_r11-0x4

etc..

That is the expected pattern for a CFI adorned indirect call. In
particular objtool checks for that 'ud2' being there. 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-10  7:44     ` Peter Zijlstra
@ 2025-10-10 22:30       ` Nathan Chancellor
  2025-10-10 22:53         ` Kees Cook
  2025-10-13  8:26         ` Peter Zijlstra
  0 siblings, 2 replies; 10+ messages in thread
From: Nathan Chancellor @ 2025-10-10 22:30 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Fri, Oct 10, 2025 at 09:44:46AM +0200, Peter Zijlstra wrote:
> That's here... and that is indeed broken. Also note how it zeros r11
> right before calling it.
> 
> AFAICT this is:
> 
>         host->phy_init_fn = of_device_get_match_data(dev);
>         err = host->phy_init_fn(host);
> 
> Where it has decided that of_device_get_match_data() *will* return NULL
> and then helpfully emits (*NULL)(); or something like that. And then

Oh duh because it will :)

  $ rg '^(# )?CONFIG_OF' .config
  1528:# CONFIG_OF is not set

which means that of_device_get_match_data() is always NULL:

  static inline const void *of_device_get_match_data(const struct device *dev)
  {
      return NULL;
  }

> forgets to add CFI bits on for extra fun and games.

which means this is another instance of what Sami mentioned happening on
another report of a similar issue

  https://lore.kernel.org/CABCJKue1wCB6jBLYUc-fAEzpyQWHXwbk8R5GBaZCkCao0EQZPA@mail.gmail.com/

which does somewhat make sense because what's the point of setting up
the CFI call if you know nothing can actually make use of it since we
will crash when trying to indirectly call a NULL pointer?

Something like this would avoid this issue then.

Cheers,
Nathan

diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 213028052aa5..15514c9c1927 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -981,7 +981,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 		goto err_clk_disable;
 
 	host->phy_init_fn = of_device_get_match_data(dev);
-	err = host->phy_init_fn(host);
+	err = host->phy_init_fn ? host->phy_init_fn(host) : -ENODEV;
 	if (err) {
 		dev_err(dev, "failed to init PCIe PHY\n");
 		goto err_clk_disable;

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-10 22:30       ` Nathan Chancellor
@ 2025-10-10 22:53         ` Kees Cook
  2025-10-13  8:26         ` Peter Zijlstra
  1 sibling, 0 replies; 10+ messages in thread
From: Kees Cook @ 2025-10-10 22:53 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Peter Zijlstra, llvm, oe-kbuild-all, linux-kernel, x86,
	Ingo Molnar, kernel test robot

On Fri, Oct 10, 2025 at 03:30:12PM -0700, Nathan Chancellor wrote:
> On Fri, Oct 10, 2025 at 09:44:46AM +0200, Peter Zijlstra wrote:
> > That's here... and that is indeed broken. Also note how it zeros r11
> > right before calling it.
> > 
> > AFAICT this is:
> > 
> >         host->phy_init_fn = of_device_get_match_data(dev);
> >         err = host->phy_init_fn(host);
> > 
> > Where it has decided that of_device_get_match_data() *will* return NULL
> > and then helpfully emits (*NULL)(); or something like that. And then
> 
> Oh duh because it will :)
> 
>   $ rg '^(# )?CONFIG_OF' .config
>   1528:# CONFIG_OF is not set
> 
> which means that of_device_get_match_data() is always NULL:
> 
>   static inline const void *of_device_get_match_data(const struct device *dev)
>   {
>       return NULL;
>   }
> 
> > forgets to add CFI bits on for extra fun and games.
> 
> which means this is another instance of what Sami mentioned happening on
> another report of a similar issue
> 
>   https://lore.kernel.org/CABCJKue1wCB6jBLYUc-fAEzpyQWHXwbk8R5GBaZCkCao0EQZPA@mail.gmail.com/
> 
> which does somewhat make sense because what's the point of setting up
> the CFI call if you know nothing can actually make use of it since we
> will crash when trying to indirectly call a NULL pointer?
> 
> Something like this would avoid this issue then.
> 
> Cheers,
> Nathan
> 
> diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
> index 213028052aa5..15514c9c1927 100644
> --- a/drivers/pci/controller/pcie-rcar-host.c
> +++ b/drivers/pci/controller/pcie-rcar-host.c
> @@ -981,7 +981,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  		goto err_clk_disable;
>  
>  	host->phy_init_fn = of_device_get_match_data(dev);
> -	err = host->phy_init_fn(host);
> +	err = host->phy_init_fn ? host->phy_init_fn(host) : -ENODEV;
>  	if (err) {
>  		dev_err(dev, "failed to init PCIe PHY\n");
>  		goto err_clk_disable;

Much preferred over "always crash" ;) Nice digging!

Reviewed-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-10 22:30       ` Nathan Chancellor
  2025-10-10 22:53         ` Kees Cook
@ 2025-10-13  8:26         ` Peter Zijlstra
  2025-10-13 18:30           ` Nathan Chancellor
  1 sibling, 1 reply; 10+ messages in thread
From: Peter Zijlstra @ 2025-10-13  8:26 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Fri, Oct 10, 2025 at 03:30:12PM -0700, Nathan Chancellor wrote:
> On Fri, Oct 10, 2025 at 09:44:46AM +0200, Peter Zijlstra wrote:
> > That's here... and that is indeed broken. Also note how it zeros r11
> > right before calling it.
> > 
> > AFAICT this is:
> > 
> >         host->phy_init_fn = of_device_get_match_data(dev);
> >         err = host->phy_init_fn(host);
> > 
> > Where it has decided that of_device_get_match_data() *will* return NULL
> > and then helpfully emits (*NULL)(); or something like that. And then
> 
> Oh duh because it will :)
> 
>   $ rg '^(# )?CONFIG_OF' .config
>   1528:# CONFIG_OF is not set
> 
> which means that of_device_get_match_data() is always NULL:
> 
>   static inline const void *of_device_get_match_data(const struct device *dev)
>   {
>       return NULL;
>   }
> 
> > forgets to add CFI bits on for extra fun and games.
> 
> which means this is another instance of what Sami mentioned happening on
> another report of a similar issue
> 
>   https://lore.kernel.org/CABCJKue1wCB6jBLYUc-fAEzpyQWHXwbk8R5GBaZCkCao0EQZPA@mail.gmail.com/

Ah yes -- I had missed that :/

> which does somewhat make sense because what's the point of setting up
> the CFI call if you know nothing can actually make use of it since we
> will crash when trying to indirectly call a NULL pointer?

As Sami says, it would be really nice if clang would at least WARN about
emitting an unconditional NULL call like that. I mean, it *knows* its
going to crash and burn at that point, right?

> Something like this would avoid this issue then.

Yes, this seems reasonable -- even if the driver should perhaps
mandate/depend on CONFIG_OF, making sure to behave when NULL does get
returned is definitely a good thing!.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

> Cheers,
> Nathan
> 
> diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
> index 213028052aa5..15514c9c1927 100644
> --- a/drivers/pci/controller/pcie-rcar-host.c
> +++ b/drivers/pci/controller/pcie-rcar-host.c
> @@ -981,7 +981,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
>  		goto err_clk_disable;
>  
>  	host->phy_init_fn = of_device_get_match_data(dev);
> -	err = host->phy_init_fn(host);
> +	err = host->phy_init_fn ? host->phy_init_fn(host) : -ENODEV;
>  	if (err) {
>  		dev_err(dev, "failed to init PCIe PHY\n");
>  		goto err_clk_disable;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-13  8:26         ` Peter Zijlstra
@ 2025-10-13 18:30           ` Nathan Chancellor
  2025-10-13 18:50             ` Peter Zijlstra
  0 siblings, 1 reply; 10+ messages in thread
From: Nathan Chancellor @ 2025-10-13 18:30 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Mon, Oct 13, 2025 at 10:26:29AM +0200, Peter Zijlstra wrote:
> On Fri, Oct 10, 2025 at 03:30:12PM -0700, Nathan Chancellor wrote:
> > which does somewhat make sense because what's the point of setting up
> > the CFI call if you know nothing can actually make use of it since we
> > will crash when trying to indirectly call a NULL pointer?
> 
> As Sami says, it would be really nice if clang would at least WARN about
> emitting an unconditional NULL call like that. I mean, it *knows* its
> going to crash and burn at that point, right?

Yeah, I agree. It would have to happen after optimizations and the
infrastructure for reporting those instances back up to the frontend
is... not great IIRC but I will see if I can file something upstream.

Is there any way for objtool to detect these instances and emit a
slightly differently worded message? Figured it was worth asking ;)

> > Something like this would avoid this issue then.
> 
> Yes, this seems reasonable -- even if the driver should perhaps
> mandate/depend on CONFIG_OF, making sure to behave when NULL does get
> returned is definitely a good thing!.
> 
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Thanks, I have sent this for review with your tag and Kees's:

https://lore.kernel.org/20251013-rcar_pcie_probe-avoid-nocfi-objtool-warning-v1-1-552876b94f04@kernel.org/

Cheers,
Nathan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-13 18:30           ` Nathan Chancellor
@ 2025-10-13 18:50             ` Peter Zijlstra
  2025-10-13 20:08               ` Peter Zijlstra
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Zijlstra @ 2025-10-13 18:50 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot

On Mon, Oct 13, 2025 at 11:30:59AM -0700, Nathan Chancellor wrote:

> Is there any way for objtool to detect these instances and emit a
> slightly differently worded message? Figured it was worth asking ;)

Objtool doesn't really do value tracking, but I'll see if I can hack
something together.

That is, as long as its always:

  xor %r11, %r11
  cs call __x86_indirect_thunk_r11

without any instructions in between, it should be relatively straight
forward. But the moment there can be anything in between we need to
track the value of r11 back from the call or something.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call!
  2025-10-13 18:50             ` Peter Zijlstra
@ 2025-10-13 20:08               ` Peter Zijlstra
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Zijlstra @ 2025-10-13 20:08 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: llvm, oe-kbuild-all, linux-kernel, x86, Ingo Molnar, Kees Cook,
	kernel test robot, Josh Poimboeuf

On Mon, Oct 13, 2025 at 08:50:12PM +0200, Peter Zijlstra wrote:
> On Mon, Oct 13, 2025 at 11:30:59AM -0700, Nathan Chancellor wrote:
> 
> > Is there any way for objtool to detect these instances and emit a
> > slightly differently worded message? Figured it was worth asking ;)
> 
> Objtool doesn't really do value tracking, but I'll see if I can hack
> something together.
> 
> That is, as long as its always:
> 
>   xor %r11, %r11
>   cs call __x86_indirect_thunk_r11
> 
> without any instructions in between, it should be relatively straight
> forward. But the moment there can be anything in between we need to
> track the value of r11 back from the call or something.

vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: (*NULL)() FTW!

---
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 0ad5cc70ecbe..2fb92d944d8c 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -236,6 +236,19 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
 		}
 		break;
 
+	case 0x31: /* XOR */
+		if (!opts.cfi)
+			break;
+
+		/* kCFI requires all indirect calls through r11 */
+
+		if (modrm_mod == 3 && modrm_reg == modrm_rm) {
+			/* XOR %reg, %reg */
+			if (modrm_reg == 11)
+				insn->type = INSN_ZERO_INDIRECT;
+		}
+		break;
+
 	case 0x50 ... 0x57:
 
 		/* push reg */
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a5770570b106..9382d5d18885 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4029,7 +4029,13 @@ static int validate_retpoline(struct objtool_file *file)
 			struct instruction *prev =
 				prev_insn_same_sym(file, insn);
 
-			if (!prev || prev->type != INSN_BUG) {
+			if (!prev) {
+				WARN_INSN(insn, "indirect call as first instruction!");
+				warnings++;
+			} else if (prev->type == INSN_ZERO_INDIRECT) {
+				WARN_INSN(insn, "(*NULL)() FTW!");
+				warnings++;
+			} else if (prev->type != INSN_BUG) {
 				WARN_INSN(insn, "no-cfi indirect call!");
 				warnings++;
 			}
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index be33c7b43180..d9fea571a455 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -30,6 +30,7 @@ enum insn_type {
 	INSN_TRAP,
 	INSN_ENDBR,
 	INSN_LEA_RIP,
+	INSN_ZERO_INDIRECT,
 	INSN_OTHER,
 };
 

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-10-13 20:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-09 13:07 [tip:x86/core 1/1] vmlinux.o: warning: objtool: rcar_pcie_probe+0x13e: no-cfi indirect call! kernel test robot
2025-10-10  3:20 ` Nathan Chancellor
2025-10-10  7:10   ` Peter Zijlstra
2025-10-10  7:44     ` Peter Zijlstra
2025-10-10 22:30       ` Nathan Chancellor
2025-10-10 22:53         ` Kees Cook
2025-10-13  8:26         ` Peter Zijlstra
2025-10-13 18:30           ` Nathan Chancellor
2025-10-13 18:50             ` Peter Zijlstra
2025-10-13 20:08               ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox