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# Copyright 2015, Richard Lowe.
15
16tmpdir=/tmp/test.$$
17mkdir $tmpdir
18cd $tmpdir
19
20cleanup() {
21    cd /
22    rm -fr $tmpdir
23}
24
25trap 'cleanup' EXIT
26
27cat > tester.c <<EOF
28#include <stdio.h>
29#include <unistd.h>
30
31int
32main(int argc, char **argv)
33{
34	sleep(10000);
35	return (0);
36}
37EOF
38
39gcc -o tester-aslr tester.c -Wl,-z,aslr=enabled
40gcc -o tester-noaslr tester.c -Wl,-z,aslr=disabled
41
42# This is the easiest way I've found to get many many DTs, but it's gross
43gcc -o many-dts-aslr tester.c -Wl,-z,aslr=enabled $(for elt in /usr/lib/lib*.so; do echo -Wl,-N,$(basename $elt); done)
44gcc -o many-dts-noaslr tester.c -Wl,-z,aslr=disabled $(for elt in /usr/lib/lib*.so; do echo -Wl,-N,$(basename $elt); done)
45
46check() {
47    bin=$1
48    state=$2
49    set=$3
50    ret=0
51
52    $bin &
53    pid=$!
54    psecflags $pid | grep -q "${set}:.*aslr"
55    (( $? != $state )) && ret=1
56    kill -9 $pid
57    return $ret
58}
59
60fail() {
61    echo $@
62    exit 1
63}
64
65psecflags -s none $$
66check ./tester-aslr 0 E || fail "DT_SUNW_ASLR 1 failed"
67check ./many-dts-aslr 0 E || fail "DT_SUNW_ASLR 1 with many DTs failed"
68check ./tester-aslr 1 I || fail "DT_SUNW_ASLR 1 incorrectly set the inheritable flag"
69
70psecflags -s aslr $$
71check ./tester-noaslr 1 E || fail "DT_SUNW_ASLR 0 failed"
72check ./many-dts-noaslr 1 E || fail "DT_SUNW_ASLR 0 with many DTs failed"
73
74