module: Make sure relocations are applied to the per-CPU section
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 10 Jun 2025 16:33:28 +0000 (18:33 +0200)
committerDaniel Gomez <da.gomez@samsung.com>
Tue, 8 Jul 2025 18:52:30 +0000 (20:52 +0200)
The per-CPU data section is handled differently than the other sections.
The memory allocations requires a special __percpu pointer and then the
section is copied into the view of each CPU. Therefore the SHF_ALLOC
flag is removed to ensure move_module() skips it.

Later, relocations are applied and apply_relocations() skips sections
without SHF_ALLOC because they have not been copied. This also skips the
per-CPU data section.
The missing relocations result in a NULL pointer on x86-64 and very
small values on x86-32. This results in a crash because it is not
skipped like NULL pointer would and can't be dereferenced.

Such an assignment happens during static per-CPU lock initialisation
with lockdep enabled.

Allow relocation processing for the per-CPU section even if SHF_ALLOC is
missing.

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202506041623.e45e4f7d-lkp@intel.com
Fixes: 1a6100caae425 ("Don't relocate non-allocated regions in modules.") #v2.6.1-rc3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Link: https://lore.kernel.org/r/20250610163328.URcsSUC1@linutronix.de
Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
Message-ID: <20250610163328.URcsSUC1@linutronix.de>

kernel/module/main.c

index 7822b91fca6b607bb066e3d4d9a01911b51ea132..c2c08007029d1b17072e70f6d89ba4f87874c8c0 100644 (file)
@@ -1573,8 +1573,14 @@ static int apply_relocations(struct module *mod, const struct load_info *info)
                if (infosec >= info->hdr->e_shnum)
                        continue;
 
-               /* Don't bother with non-allocated sections */
-               if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))
+               /*
+                * Don't bother with non-allocated sections.
+                * An exception is the percpu section, which has separate allocations
+                * for individual CPUs. We relocate the percpu section in the initial
+                * ELF template and subsequently copy it to the per-CPU destinations.
+                */
+               if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC) &&
+                   (!infosec || infosec != info->index.pcpu))
                        continue;
 
                if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH)