xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/lkdtm/stack-entropy.sh (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker#!/bin/sh
2*053f45beSAndroid Build Coastguard Worker# SPDX-License-Identifier: GPL-2.0
3*053f45beSAndroid Build Coastguard Worker#
4*053f45beSAndroid Build Coastguard Worker# Measure kernel stack entropy by sampling via LKDTM's REPORT_STACK test.
5*053f45beSAndroid Build Coastguard Workerset -e
6*053f45beSAndroid Build Coastguard Workersamples="${1:-1000}"
7*053f45beSAndroid Build Coastguard WorkerTRIGGER=/sys/kernel/debug/provoke-crash/DIRECT
8*053f45beSAndroid Build Coastguard WorkerKSELFTEST_SKIP_TEST=4
9*053f45beSAndroid Build Coastguard Worker
10*053f45beSAndroid Build Coastguard Worker# Verify we have LKDTM available in the kernel.
11*053f45beSAndroid Build Coastguard Workerif [ ! -r $TRIGGER ] ; then
12*053f45beSAndroid Build Coastguard Worker	/sbin/modprobe -q lkdtm || true
13*053f45beSAndroid Build Coastguard Worker	if [ ! -r $TRIGGER ] ; then
14*053f45beSAndroid Build Coastguard Worker		echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)"
15*053f45beSAndroid Build Coastguard Worker	else
16*053f45beSAndroid Build Coastguard Worker		echo "Cannot write $TRIGGER (need to run as root?)"
17*053f45beSAndroid Build Coastguard Worker	fi
18*053f45beSAndroid Build Coastguard Worker	# Skip this test
19*053f45beSAndroid Build Coastguard Worker	exit $KSELFTEST_SKIP_TEST
20*053f45beSAndroid Build Coastguard Workerfi
21*053f45beSAndroid Build Coastguard Worker
22*053f45beSAndroid Build Coastguard Worker# Capture dmesg continuously since it may fill up depending on sample size.
23*053f45beSAndroid Build Coastguard Workerlog=$(mktemp -t stack-entropy-XXXXXX)
24*053f45beSAndroid Build Coastguard Workerdmesg --follow >"$log" & pid=$!
25*053f45beSAndroid Build Coastguard Workerreport=-1
26*053f45beSAndroid Build Coastguard Workerfor i in $(seq 1 $samples); do
27*053f45beSAndroid Build Coastguard Worker        echo "REPORT_STACK" > $TRIGGER
28*053f45beSAndroid Build Coastguard Worker	if [ -t 1 ]; then
29*053f45beSAndroid Build Coastguard Worker		percent=$(( 100 * $i / $samples ))
30*053f45beSAndroid Build Coastguard Worker		if [ "$percent" -ne "$report" ]; then
31*053f45beSAndroid Build Coastguard Worker			/bin/echo -en "$percent%\r"
32*053f45beSAndroid Build Coastguard Worker			report="$percent"
33*053f45beSAndroid Build Coastguard Worker		fi
34*053f45beSAndroid Build Coastguard Worker	fi
35*053f45beSAndroid Build Coastguard Workerdone
36*053f45beSAndroid Build Coastguard Workerkill "$pid"
37*053f45beSAndroid Build Coastguard Worker
38*053f45beSAndroid Build Coastguard Worker# Count unique offsets since last run.
39*053f45beSAndroid Build Coastguard Workerseen=$(tac "$log" | grep -m1 -B"$samples"0 'Starting stack offset' | \
40*053f45beSAndroid Build Coastguard Worker	grep 'Stack offset' | awk '{print $NF}' | sort | uniq -c | wc -l)
41*053f45beSAndroid Build Coastguard Workerbits=$(echo "obase=2; $seen" | bc | wc -L)
42*053f45beSAndroid Build Coastguard Workerecho "Bits of stack entropy: $bits"
43*053f45beSAndroid Build Coastguard Workerrm -f "$log"
44*053f45beSAndroid Build Coastguard Worker
45*053f45beSAndroid Build Coastguard Worker# We would expect any functional stack randomization to be at least 5 bits.
46*053f45beSAndroid Build Coastguard Workerif [ "$bits" -lt 5 ]; then
47*053f45beSAndroid Build Coastguard Worker	echo "Stack entropy is low! Booted without 'randomize_kstack_offset=y'?"
48*053f45beSAndroid Build Coastguard Worker	exit 1
49*053f45beSAndroid Build Coastguard Workerelse
50*053f45beSAndroid Build Coastguard Worker	exit 0
51*053f45beSAndroid Build Coastguard Workerfi
52