| #!/bin/bash | |
| # SPDX-License-Identifier: GPL-2.0 | |
| # | |
| # An absolute symbol and an __ADDRESSABLE() pointer must not disturb the | |
| # function being patched. | |
| # | |
| # A SHN_ABS symbol has no section, so any walk of sym->sec which does not check | |
| # dereferences NULL -- and the kernel has plenty, from linker scripts and from | |
| # .set in assembly. __ADDRESSABLE() emits a pointer into .discard.addressable | |
| # to keep a symbol referenced; it means nothing to a livepatch and is discarded | |
| # at link time, but it is a relocation like any other and gets looked at. | |
| # | |
| # Neither is what the patch changes. The failure this guards against is not a | |
| # wrong answer but a crash or an error on input the kernel produces routinely, | |
| # which would make any function near one unpatchable. | |
| # | |
| # Not isolated to a single guard: the absolute symbol here has zero length, so | |
| # it is excluded before the section check is reached and removing that check | |
| # alone changes nothing observable. This stands as a check on the behaviour | |
| # rather than on the line which produces it. | |
| # | |
| # Covers the same ground as corpus/x86_64/checksum-abs-sym-skip and | |
| # addressable-symbols in Joe Lawrence's klp-build unit test corpus. | |
| . "$(dirname "$0")/../lib.sh" | |
| setup | |
| build_pair abs_and_addressable.c | |
| # The premise: the fixture really did produce both. | |
| in_symbols orig.o | grep -q 'ABS.*abs_sym' || | |
| probe_skip "assembler did not make abs_sym absolute here" | |
| assert_input_section .discard.addressable | |
| # Checksumming has to survive them, and still see the function that changed. | |
| run_checksum | |
| assert_checksum_differs target | |
| assert_checksum_matches helper | |
| # So does the diff. | |
| run_diff | |
| assert_patched target | |
| assert_not_patched helper | |
| # An absolute symbol has no address to record a checksum against, so it gets | |
| # no entry -- the reference to it is what mattered, not the symbol itself. | |
| in_relocs orig.o | awk '/rela\.discard\.sym_checksum/,/^$/' | grep -qw abs_sym && | |
| fail "absolute symbol got a checksum entry" | |
| pass "absolute and __ADDRESSABLE symbols do not disturb the patched function" |