1 #!/usr/bin/ksh
   2 #
   3 #
   4 # This file and its contents are supplied under the terms of the
   5 # Common Development and Distribution License ("CDDL"), version 1.0.
   6 # You may only use this file in accordance with the terms of version
   7 # 1.0 of the CDDL.
   8 #
   9 # A full copy of the text of the CDDL should have accompanied this
  10 # source.  A copy of the CDDL is also available via the Internet at
  11 # http://www.illumos.org/license/CDDL.
  12 #
  13 
  14 #
  15 # Copyright 2023 Oxide Computer Company
  16 #
  17 
  18 #
  19 # This test goes through and runs our 32 and 64-bit bad xsave contexts
  20 # tests using getcontextx() in lieu of the signal handler to create
  21 # invalid states. setcontext(2) in libc will try to kill the process if
  22 # this fails in most situations, so we basically go through and detect
  23 # that this is the case we expect (e.g. the system call returned an
  24 # error) and go from there.
  25 #
  26 
  27 unalias -a
  28 set -o pipefail
  29 
  30 xsave_arg0="$(basename $0)"
  31 xsave_dir="$(dirname $0)"
  32 xsave_bad32="$xsave_dir/xsave_baducontext.32"
  33 xsave_bad64="$xsave_dir/xsave_baducontext.64"
  34 xsave_exit=0
  35 
  36 warn()
  37 {
  38         typeset msg="$*"
  39         echo "TEST FAILED: $msg" >&2
  40         xsave_exit=1
  41 }
  42 
  43 run_single()
  44 {
  45         typeset prog=$1
  46         typeset caseno=$2
  47         typeset info=
  48         typeset ret=
  49         typeset desc=
  50         typeset errno=
  51 
  52         if ! info=$($prog -i $caseno); then
  53                 warn "failed to get test information for case $caseno"
  54                 return
  55         fi
  56 
  57         if ! eval $info || [[ -z "$desc" ]] || [[ -z "$errno" ]]; then
  58                 warn "failed to set test information"
  59         fi
  60 
  61         dtrace -q -w -c "$prog -r $caseno" -s /dev/stdin <<EOF
  62 syscall::setcontext:return
  63 /pid == \$target && arg1 != 0 && errno == $errno/
  64 {
  65         printf("TEST PASSED: $desc\n");
  66         stop();
  67         raise(SIGKILL);
  68         exit(0);
  69 }
  70 
  71 syscall::setcontext:return
  72 /pid == \$target && arg1 != 0 && errno != $errno/
  73 {
  74         printf("errno mismatch: found %d, expected $errno\n", errno);
  75         printf("TEST FAILED: $desc\n");
  76         stop();
  77         raise(SIGKILL);
  78         exit(1);
  79 }
  80 
  81 proc:::exit
  82 /pid == \$target/
  83 {
  84         printf("TEST FAILED: $desc: exited normally\n");
  85         exit(1);
  86 }
  87 EOF
  88         if (( $? != 0 )); then
  89                 xsave_exit=1
  90         fi
  91 }
  92 
  93 run_prog()
  94 {
  95         typeset prog="$1"
  96         typeset count=
  97 
  98         printf "Beginning tests from %s\n" "$prog"
  99         count=$($prog -c)
 100         if (( $? != 0 || count <= 0)); then
 101                 warn "failed to get entry count for $prog"
 102                 return
 103         fi
 104 
 105         for ((i = 0; i < count; i++)) {
 106                 run_single $prog $i
 107         }
 108 }
 109 
 110 run_prog $xsave_bad32
 111 run_prog $xsave_bad64
 112 
 113 if (( xsave_exit == 0 )); then
 114         printf "All tests passed successfully\n"
 115 fi
 116 exit $xsave_exit