xref: /linux/tools/objtool/tests/generic/test-ubsan-noise.sh (revision 5b6dca02b3e2254d2fd5706d76d7ab4610a67296)
1*41ca5150SSong Liu#!/bin/bash
2*41ca5150SSong Liu# SPDX-License-Identifier: GPL-2.0
3*41ca5150SSong Liu#
4*41ca5150SSong Liu# UBSAN instrumentation in an unchanged function must not make it look changed.
5*41ca5150SSong Liu#
6*41ca5150SSong Liu# Every instrumented operation gets a per-callsite metadata object in an
7*41ca5150SSong Liu# anonymous data section -- .data..Lubsan_data and .data..Lubsan_type from GCC,
8*41ca5150SSong Liu# .data..L__unnamed_ from Clang -- whose names are compiler-generated and mean
9*41ca5150SSong Liu# nothing across a rebuild.  is_uncorrelated_section() exists so klp diff does
10*41ca5150SSong Liu# not try to pair them up.
11*41ca5150SSong Liu#
12*41ca5150SSong Liu# Without that, the metadata belonging to a function nobody touched compares as
13*41ca5150SSong Liu# different and drags the function into the patch.  A livepatch which replaces
14*41ca5150SSong Liu# functions the patch never changed is not a build failure: it is a larger
15*41ca5150SSong Liu# patch than intended, taking its dependencies with it, and every extra
16*41ca5150SSong Liu# function is one more that can fail to correlate or to apply.
17*41ca5150SSong Liu#
18*41ca5150SSong Liu# Covers the same ground as corpus/x86_64-ubsan/{ubsan-shift-noise,
19*41ca5150SSong Liu# ubsan-metadata-data-section,gcc-ubsan-anonymous-data,ubsan-handler-cloning}
20*41ca5150SSong Liu# and corpus/x86_64-llvm-ubsan/{clang-ubsan-bounds-noise,
21*41ca5150SSong Liu# clang-ubsan-handler-cloning} in Joe Lawrence's klp-build unit test corpus.
22*41ca5150SSong Liu
23*41ca5150SSong Liu. "$(dirname "$0")/../lib.sh"
24*41ca5150SSong Liu
25*41ca5150SSong Liusetup
26*41ca5150SSong Liubuild_pair ubsan_noise.c -fsanitize=shift
27*41ca5150SSong Liu
28*41ca5150SSong Liu# The premise: this compiler really did instrument, and left its metadata in an
29*41ca5150SSong Liu# anonymous section.  Without that the test is just test-basic again.
30*41ca5150SSong Liuubsan_sec="$(in_sections orig.o |
31*41ca5150SSong Liu	grep -oE '\.data\.\.L(ubsan_data|__unnamed_)[A-Za-z0-9_.]*' | head -1)"
32*41ca5150SSong Liu[ -n "$ubsan_sec" ] ||
33*41ca5150SSong Liu	probe_skip "compiler emitted no anonymous UBSAN data section"
34*41ca5150SSong Liuassert_input_symbol untouched
35*41ca5150SSong Liu
36*41ca5150SSong Liurun_diff
37*41ca5150SSong Liu
38*41ca5150SSong Liu# The changed function is patched, and the untouched one is left alone despite
39*41ca5150SSong Liu# carrying instrumentation of its own.
40*41ca5150SSong Liuassert_patched touched
41*41ca5150SSong Liuassert_not_patched untouched
42*41ca5150SSong Liu
43*41ca5150SSong Liu# The handler the patched code calls has to come with it, or the clone calls
44*41ca5150SSong Liu# nothing when its check fires.
45*41ca5150SSong Liuout_symbols | grep -q '__ubsan_handle_' ||
46*41ca5150SSong Liu	fail "no __ubsan_handle_* reference in the patched output"
47*41ca5150SSong Liu
48*41ca5150SSong Liupass "UBSAN metadata in an unchanged function does not drag it into the patch"
49