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