1*91c67484SSong Liu#!/bin/bash 2*91c67484SSong Liu# SPDX-License-Identifier: GPL-2.0 3*91c67484SSong Liu# 4*91c67484SSong Liu# An absolute symbol and an __ADDRESSABLE() pointer must not disturb the 5*91c67484SSong Liu# function being patched. 6*91c67484SSong Liu# 7*91c67484SSong Liu# A SHN_ABS symbol has no section, so any walk of sym->sec which does not check 8*91c67484SSong Liu# dereferences NULL -- and the kernel has plenty, from linker scripts and from 9*91c67484SSong Liu# .set in assembly. __ADDRESSABLE() emits a pointer into .discard.addressable 10*91c67484SSong Liu# to keep a symbol referenced; it means nothing to a livepatch and is discarded 11*91c67484SSong Liu# at link time, but it is a relocation like any other and gets looked at. 12*91c67484SSong Liu# 13*91c67484SSong Liu# Neither is what the patch changes. The failure this guards against is not a 14*91c67484SSong Liu# wrong answer but a crash or an error on input the kernel produces routinely, 15*91c67484SSong Liu# which would make any function near one unpatchable. 16*91c67484SSong Liu# 17*91c67484SSong Liu# Not isolated to a single guard: the absolute symbol here has zero length, so 18*91c67484SSong Liu# it is excluded before the section check is reached and removing that check 19*91c67484SSong Liu# alone changes nothing observable. This stands as a check on the behaviour 20*91c67484SSong Liu# rather than on the line which produces it. 21*91c67484SSong Liu# 22*91c67484SSong Liu# Covers the same ground as corpus/x86_64/checksum-abs-sym-skip and 23*91c67484SSong Liu# addressable-symbols in Joe Lawrence's klp-build unit test corpus. 24*91c67484SSong Liu 25*91c67484SSong Liu. "$(dirname "$0")/../lib.sh" 26*91c67484SSong Liu 27*91c67484SSong Liusetup 28*91c67484SSong Liubuild_pair abs_and_addressable.c 29*91c67484SSong Liu 30*91c67484SSong Liu# The premise: the fixture really did produce both. 31*91c67484SSong Liuin_symbols orig.o | grep -q 'ABS.*abs_sym' || 32*91c67484SSong Liu probe_skip "assembler did not make abs_sym absolute here" 33*91c67484SSong Liuassert_input_section .discard.addressable 34*91c67484SSong Liu 35*91c67484SSong Liu# Checksumming has to survive them, and still see the function that changed. 36*91c67484SSong Liurun_checksum 37*91c67484SSong Liuassert_checksum_differs target 38*91c67484SSong Liuassert_checksum_matches helper 39*91c67484SSong Liu 40*91c67484SSong Liu# So does the diff. 41*91c67484SSong Liurun_diff 42*91c67484SSong Liuassert_patched target 43*91c67484SSong Liuassert_not_patched helper 44*91c67484SSong Liu 45*91c67484SSong Liu# An absolute symbol has no address to record a checksum against, so it gets 46*91c67484SSong Liu# no entry -- the reference to it is what mattered, not the symbol itself. 47*91c67484SSong Liuin_relocs orig.o | awk '/rela\.discard\.sym_checksum/,/^$/' | grep -qw abs_sym && 48*91c67484SSong Liu fail "absolute symbol got a checksum entry" 49*91c67484SSong Liu 50*91c67484SSong Liupass "absolute and __ADDRESSABLE symbols do not disturb the patched function" 51