Skip to content

Conversation

@liu-song-6
Copy link
Contributor

When building a livepatch, we assume symbols from "readelf -s" is the same as the order observed in kallsyms. We calculate sympos of a symbol based on this order (readelf -s). However, with gcc-14, "readelf -s" may present the symbols in a different order. For example:

With gcc 13:

32951: ffff8000802edf20 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
33497: ffff8000802fb798 236 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
47034: ffff80008044b250 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
51466: ffff8000804be260 236 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
51483: ffff8000804bf6a8 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
52287: ffff8000804cb098 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
54066: ffff800080518e38 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
58217: ffff800080575bb0 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
72912: ffff8000806c5dc0 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
73719: ffff8000806eccd0 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0

With gcc 14:

9557: ffff800080312f28 236 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
16599: ffff8000806eb060 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
17305: ffff800080711d30 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
63960: ffff800080305540 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
74577: ffff800080466030 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
78568: ffff8000804dc3e0 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
79372: ffff8000804e81c0 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
81016: ffff800080537380 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0
84685: ffff800080595428 172 FUNC LOCAL DEFAULT 2 zero_user_segments.constprop.0

Fix this by calculating sympos in another for_each_obj_symbol loop.

@joe-lawrence
Copy link
Contributor

Hi @liu-song-6 , there seems to be an issue with this change as it fails the integration tests:

[15097.951888] test_COMBINED: loading out-of-tree module taints kernel.
[15097.958202] test_COMBINED: tainting kernel with TAINT_LIVEPATCH
[15097.964212] test_COMBINED: module verification failed: signature and/or required key missing - tainting kernel
[15100.278636] livepatch: unresolvable ambiguity for symbol 'session_id' in object '(null)'

The specific patch that causes this is gcc-static-local-var-5.patch.

When looking at the klp relocations generated by this patch, it looks like the sympos is 0 for all symbols:

Relocation section '.klp.rela.vmlinux..text.audit_set_loginuid' at offset 0x14ee28 contains 5 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000038  0000009200000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.af,0 + 3
0000000000000057  0000009200000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.af,0 + 3
00000000000000b9  0000009900000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.session_id,0 - 4
00000000000000cb  0000009900000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.session_id,0 - 4
000000000000013e  000000e200000004 R_X86_64_PLT32         0000000000000000 .klp.sym.vmlinux.audit_get_tty,0 - 4

versus sympos=1 (for most symbols) from the current master HEAD:

Relocation section '.klp.rela.vmlinux..text.audit_set_loginuid' at offset 0x14ee28 contains 5 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000038  0000009200000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.af,1 + 3
0000000000000057  0000009200000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.af,1 + 3
00000000000000b9  0000009900000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.session_id,1 - 4
00000000000000cb  0000009900000002 R_X86_64_PC32          0000000000000000 .klp.sym.vmlinux.session_id,1 - 4
000000000000013e  000000e200000004 R_X86_64_PLT32         0000000000000000 .klp.sym.vmlinux.audit_get_tty,0 - 4

Perhaps it is the only integration test that contains a duplicate symbol name, so all other tests appear to work when '0' is provided? Here is a tarball of the two livepatches I created to demo the above and the vmlinux.symtab file:
sympos.tar.gz

@liu-song-6
Copy link
Contributor Author

Ah, it is a bug with the code. Let me fix it.

Copy link
Contributor

@joe-lawrence joe-lawrence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finding and fixing this up! Code looks good with one small comment suggestion.

When building a livepatch, we assume symbols from "readelf -s" is the
same as the order observed in kallsyms. We calculate sympos of a symbol
based on this order (readelf -s). However, with gcc-14, "readelf -s"
may present the symbols in a different order. For example:

With gcc 13:

32951: ffff8000802edf20   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
33497: ffff8000802fb798   236 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
47034: ffff80008044b250   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
51466: ffff8000804be260   236 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
51483: ffff8000804bf6a8   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
52287: ffff8000804cb098   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
54066: ffff800080518e38   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
58217: ffff800080575bb0   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
72912: ffff8000806c5dc0   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
73719: ffff8000806eccd0   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0

With gcc 14:

 9557: ffff800080312f28   236 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
16599: ffff8000806eb060   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
17305: ffff800080711d30   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
63960: ffff800080305540   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
74577: ffff800080466030   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
78568: ffff8000804dc3e0   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
79372: ffff8000804e81c0   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
81016: ffff800080537380   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0
84685: ffff800080595428   172 FUNC    LOCAL  DEFAULT    2 zero_user_segments.constprop.0

Fix this by calculating sympos in another for_each_obj_symbol loop.

Signed-off-by: Song Liu <song@kernel.org>
@joe-lawrence joe-lawrence merged commit 7633514 into dynup:master Mar 4, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants