Home | History | Annotate | Download | only in src
      1 #!/bin/bash
      2 # Copyright (c) 2012 The Chromium OS Authors.
      3 #
      4 # Based on:
      5 # http://bazaar.launchpad.net/~ubuntu-bugcontrol/qa-regression-testing/master/view/head:/scripts/kernel-security/ptrace/ptrace-restrictions.sh
      6 # Copyright (C) 2010-2011 Canonical Ltd.
      7 # License: GPLv3
      8 # Author: Kees Cook <kees.cook (at] canonical.com>
      9 set -e
     10 if [ "$(whoami)" = "root" ]; then
     11     echo "Cannot be root for this test" >&2
     12     exit 1
     13 fi
     14 
     15 export LANG=C
     16 pid=
     17 dir=
     18 
     19 function start_sleeper()
     20 {
     21     dir=$(mktemp -d -t sleeper-XXXXXX)
     22     mkfifo "$dir"/status
     23     ./sleeper "$1" 120 >"$dir"/status &
     24     pid=$!
     25     # Wait for sleeper to start up.
     26     read status < "$dir"/status
     27 }
     28 
     29 function kill_sleeper()
     30 {
     31     disown $pid
     32     kill $pid
     33     rm -rf "$dir"
     34 }
     35 
     36 rc=0
     37 
     38 # Check we can see direct children.
     39 OUT=$(gdb -ex run -ex quit --batch ./sleeper </dev/null 2>&1)
     40 if echo "$OUT" | grep -q 'Quit anyway'; then
     41     echo "ok: children correctly allow ptrace"
     42 else
     43     echo "FAIL: Children unexpectedly not allow ptrace"
     44     rc=1
     45 fi
     46 
     47 # Check we can't see cousins.
     48 sleep 120 &
     49 pid=$!
     50 OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1)
     51 if echo "$OUT" | grep -q 'Operation not permitted'; then
     52     echo "ok: cousins correctly not allow ptrace"
     53 else
     54     echo "FAIL: cousins unexpectedly allow ptrace"
     55     rc=1
     56 fi
     57 
     58 # Validate we can see cousin /proc entries.
     59 if ls -la /proc/$pid/exe >/dev/null 2>&1; then
     60     echo "ok: cousins correctly visible in /proc"
     61 else
     62     echo "FAIL: cousins unexpectedly invisible in /proc"
     63     rc=1
     64 fi
     65 
     66 # Check we can't attach to init.
     67 OUT=$(gdb -ex "attach 1" -ex "quit" --batch </dev/null 2>&1)
     68 if echo "$OUT" | grep -q 'Operation not permitted'; then
     69     echo "ok: init correctly not allowing ptrace"
     70 else
     71     echo "FAIL: init unexpectedly allowed ptrace"
     72     rc=1
     73 fi
     74 
     75 # Check we can't see init.
     76 if ! ls -la /proc/1/exe >/dev/null 2>&1; then
     77     echo "ok: init correctly invisible in /proc"
     78 else
     79     echo "FAIL: init unexpectedly visible in /proc"
     80     rc=1
     81 fi
     82 
     83 # Drop the sleep process and destroy it without disrupting the shell.
     84 disown $pid
     85 kill $pid
     86 
     87 # Validate that prctl(PR_SET_PTRACER, 0, ...) works to delete tracer.
     88 start_sleeper 0
     89 OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1)
     90 prctl="prctl(PR_SET_PTRACER, 0, ...)"
     91 if echo "$OUT" | grep -q 'Operation not permitted'; then
     92     echo "ok: $prctl correctly not allowed ptrace"
     93 else
     94     echo "FAIL: $prctl unexpectedly allowed ptrace"
     95     rc=1
     96 fi
     97 kill_sleeper
     98 
     99 # Validate near ancestor allowed with PR_SET_PTRACER use.
    100 start_sleeper $$
    101 OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1)
    102 prctl="prctl(PR_SET_PTRACER, parent, ...)"
    103 if echo "$OUT" | grep -q 'Quit anyway'; then
    104     echo "ok: $prctl correctly allowed ptrace"
    105 else
    106     echo "FAIL: $prctl unexpectedly not allowed ptrace"
    107     rc=1
    108 fi
    109 kill_sleeper
    110 
    111 # Validate distant ancestor allowed with PR_SET_PTRACER use.
    112 start_sleeper 1
    113 OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1)
    114 prctl="prctl(PR_SET_PTRACER, 1, ...)"
    115 if echo "$OUT" | grep -q 'Quit anyway'; then
    116     echo "ok: $prctl correctly allowed ptrace"
    117 else
    118     echo "FAIL: $prctl unexpectedly not allowed ptrace"
    119     rc=1
    120 fi
    121 kill_sleeper
    122 
    123 # Validate -1 disables protection.
    124 start_sleeper -1
    125 OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1)
    126 prctl="prctl(PR_SET_PTRACER, -1, ...)"
    127 if echo "$OUT" | grep -q 'Quit anyway'; then
    128     echo "ok: $prctl correctly allowed ptrace"
    129 else
    130     echo "FAIL: $prctl unexpectedly not allowed ptrace"
    131     rc=1
    132 fi
    133 kill_sleeper
    134 
    135 exit $rc
    136