stack-entropy.sh 1.4 KB

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