162306a36Sopenharmony_ci#!/bin/sh 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# 462306a36Sopenharmony_ci# Measure kernel stack entropy by sampling via LKDTM's REPORT_STACK test. 562306a36Sopenharmony_ciset -e 662306a36Sopenharmony_cisamples="${1:-1000}" 762306a36Sopenharmony_ciTRIGGER=/sys/kernel/debug/provoke-crash/DIRECT 862306a36Sopenharmony_ciKSELFTEST_SKIP_TEST=4 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci# Verify we have LKDTM available in the kernel. 1162306a36Sopenharmony_ciif [ ! -r $TRIGGER ] ; then 1262306a36Sopenharmony_ci /sbin/modprobe -q lkdtm || true 1362306a36Sopenharmony_ci if [ ! -r $TRIGGER ] ; then 1462306a36Sopenharmony_ci echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)" 1562306a36Sopenharmony_ci else 1662306a36Sopenharmony_ci echo "Cannot write $TRIGGER (need to run as root?)" 1762306a36Sopenharmony_ci fi 1862306a36Sopenharmony_ci # Skip this test 1962306a36Sopenharmony_ci exit $KSELFTEST_SKIP_TEST 2062306a36Sopenharmony_cifi 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci# Capture dmesg continuously since it may fill up depending on sample size. 2362306a36Sopenharmony_cilog=$(mktemp -t stack-entropy-XXXXXX) 2462306a36Sopenharmony_cidmesg --follow >"$log" & pid=$! 2562306a36Sopenharmony_cireport=-1 2662306a36Sopenharmony_cifor i in $(seq 1 $samples); do 2762306a36Sopenharmony_ci echo "REPORT_STACK" > $TRIGGER 2862306a36Sopenharmony_ci if [ -t 1 ]; then 2962306a36Sopenharmony_ci percent=$(( 100 * $i / $samples )) 3062306a36Sopenharmony_ci if [ "$percent" -ne "$report" ]; then 3162306a36Sopenharmony_ci /bin/echo -en "$percent%\r" 3262306a36Sopenharmony_ci report="$percent" 3362306a36Sopenharmony_ci fi 3462306a36Sopenharmony_ci fi 3562306a36Sopenharmony_cidone 3662306a36Sopenharmony_cikill "$pid" 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci# Count unique offsets since last run. 3962306a36Sopenharmony_ciseen=$(tac "$log" | grep -m1 -B"$samples"0 'Starting stack offset' | \ 4062306a36Sopenharmony_ci grep 'Stack offset' | awk '{print $NF}' | sort | uniq -c | wc -l) 4162306a36Sopenharmony_cibits=$(echo "obase=2; $seen" | bc | wc -L) 4262306a36Sopenharmony_ciecho "Bits of stack entropy: $bits" 4362306a36Sopenharmony_cirm -f "$log" 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci# We would expect any functional stack randomization to be at least 5 bits. 4662306a36Sopenharmony_ciif [ "$bits" -lt 5 ]; then 4762306a36Sopenharmony_ci echo "Stack entropy is low! Booted without 'randomize_kstack_offset=y'?" 4862306a36Sopenharmony_ci exit 1 4962306a36Sopenharmony_cielse 5062306a36Sopenharmony_ci exit 0 5162306a36Sopenharmony_cifi 52