| #!/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 |