| #!/bin/sh | 
 | # SPDX-License-Identifier: GPL-2.0 | 
 | # | 
 | # Measure kernel stack entropy by sampling via LKDTM's REPORT_STACK test. | 
 | set -e | 
 | samples="${1:-1000}" | 
 | TRIGGER=/sys/kernel/debug/provoke-crash/DIRECT | 
 | KSELFTEST_SKIP_TEST=4 | 
 |  | 
 | # Verify we have LKDTM available in the kernel. | 
 | if [ ! -r $TRIGGER ] ; then | 
 | 	/sbin/modprobe -q lkdtm || true | 
 | 	if [ ! -r $TRIGGER ] ; then | 
 | 		echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)" | 
 | 	else | 
 | 		echo "Cannot write $TRIGGER (need to run as root?)" | 
 | 	fi | 
 | 	# Skip this test | 
 | 	exit $KSELFTEST_SKIP_TEST | 
 | fi | 
 |  | 
 | # Capture dmesg continuously since it may fill up depending on sample size. | 
 | log=$(mktemp -t stack-entropy-XXXXXX) | 
 | dmesg --follow >"$log" & pid=$! | 
 | report=-1 | 
 | for i in $(seq 1 $samples); do | 
 |         echo "REPORT_STACK" > $TRIGGER | 
 | 	if [ -t 1 ]; then | 
 | 		percent=$(( 100 * $i / $samples )) | 
 | 		if [ "$percent" -ne "$report" ]; then | 
 | 			/bin/echo -en "$percent%\r" | 
 | 			report="$percent" | 
 | 		fi | 
 | 	fi | 
 | done | 
 | kill "$pid" | 
 |  | 
 | # Count unique offsets since last run. | 
 | seen=$(tac "$log" | grep -m1 -B"$samples"0 'Starting stack offset' | \ | 
 | 	grep 'Stack offset' | awk '{print $NF}' | sort | uniq -c | wc -l) | 
 | bits=$(echo "obase=2; $seen" | bc | wc -L) | 
 | echo "Bits of stack entropy: $bits" | 
 | rm -f "$log" | 
 |  | 
 | # We would expect any functional stack randomization to be at least 5 bits. | 
 | if [ "$bits" -lt 5 ]; then | 
 | 	echo "Stack entropy is low! Booted without 'randomize_kstack_offset=y'?" | 
 | 	exit 1 | 
 | else | 
 | 	exit 0 | 
 | fi |