dynup / kpatch

kpatch - live kernel patching
GNU General Public License v2.0
1.49k stars 304 forks source link

kpatch_check_relocations: 2678: .debug_loc+0x2e26: out-of-range relocation #1410

Closed wardenjohn closed 2 months ago

wardenjohn commented 2 months ago

When I do kpatch, I found that an error occurred:

kpatch_check_relocations: 2678: .debug_loc+0x2e26: out-of-range relocation It seems that when this commit is merged, this error is easily occurred: commit 017015a725f802b3fa8db6106cfe280e2b2cc91d

joe-lawrence commented 2 months ago

The usual follow up questions:

wardenjohn commented 2 months ago

The error occurred as follows: Extracting new and modified ELF sections create-diff-object: ERROR: blk-throttle.o: kpatch_check_relocations: 2893: .text.__tg_update_carryover+0x4f: out-of-range relocation calculate_bytes_allowed+fffffffffffffffc blk-throttle.o: new function: calculate_bytes_allowed

And the tmp file from kpatch is uploaded.

Thanks,Joe @joe-lawrence . tmp.tar.gz

joe-lawrence commented 2 months ago

@wardenjohn - can you also attach ~/.kpatch/src/vmlinux (apologies for missing that earlier). also the input kpatch that produces this error would be handy, but not absolutely necessary if you can share that, too. Thanks!

wardenjohn commented 2 months ago

@joe-lawrence Hi,Joe

The debuginfo can be downloaded here: https://mirrors.aliyun.com/alinux/3/plus/x86_64/debug/kernels/kernel-debuginfo-5.10.134-16.3.al8.x86_64.rpm

It is a debuginfo vmlinux, I think it is enough to use.

And the patch I use is:

---
 block/blk-throttle.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 38a881cf97d0..13e4377a8b28 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -723,6 +723,12 @@ static unsigned int calculate_io_allowed(u32 iops_limit,

 static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed)
 {
+       /*
+        * Can result be wider than 64 bits?
+        * We check against 62, not 64, due to ilog2 truncation.
+        */
+       if (ilog2(bps_limit) + ilog2(jiffy_elapsed) - ilog2(HZ) > 62)
+               return U64_MAX;
        return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ);
 }

-- 
2.19.1.6.gb485710b
joe-lawrence commented 2 months ago

Hi @wardenjohn,

Using the latest kpatch-build, the 5.10.134-16.3.al8.x86_64 kernel and the files you provided, create-diff-object seems happy to me:

$ cat repro 
#!/bin/bash

source kpatch-build.env

~/kpatch/kpatch-build/create-diff-object \
        orig/block/blk-throttle.o \
        patched/block/blk-throttle.o \
    vmlinux \
    vmlinux.symtab \
    Module.symvers \
    test \
    output.o

$ ./repro 
blk-throttle.o: new function: calculate_bytes_allowed
blk-throttle.o: changed function: __tg_update_carryover
blk-throttle.o: changed function: tg_may_dispatch

Could you try out this WIP branch: https://github.com/joe-lawrence/kpatch/tree/create-repro-tarball Or more precisely, this version of kpatch-build with --debug and a new --create-bug-report option. This will create a tarball of files handy for debugging create-diff-object problems: https://raw.githubusercontent.com/joe-lawrence/kpatch/create-repro-tarball/kpatch-build/kpatch-build

(If you need to omit the vmlinux file from that tarball, that's fine, but please at least run a sum on it so I can verify that I'm downloading the same one the you are targeting.) Thanks.

wardenjohn commented 2 months ago

Hi, Joe @joe-lawrence

Oh... the latest kpatch-build seems happy to build this patch. But I am still curious about under which situation that the "out-of-range relocation" will raise. In fact, I have no idea to analysis what gcc will do to make a symbol relocation wrong.

Do you have any idea?

Thanks~~~

joe-lawrence commented 2 months ago

But I am still curious about under which situation that the "out-of-range relocation" will raise. In fact, I have no idea to analysis what gcc will do to make a symbol relocation wrong.

Do you have any idea?

Not exactly, but it may be that create-diff-object extracted changes that didn't result in a consistent ELF file (i.e. it copied something out of .debug_loc or something pointing to it that no longer matched the original assumptions that gcc make when creating the kernel build object.) But that's only a wild guess without having a repro in hand. Let us know if it happens again and we can take a better look.