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@canonical.com> 9set -e 10if [ "$(whoami)" = "root" ]; then 11 echo "Cannot be root for this test" >&2 12 exit 1 13fi 14 15export LANG=C 16pid= 17dir= 18 19function 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 29function kill_sleeper() 30{ 31 disown $pid 32 kill $pid 33 rm -rf "$dir" 34} 35 36rc=0 37 38# Check we can see direct children. 39OUT=$(gdb -ex run -ex quit --batch ./sleeper </dev/null 2>&1) 40if echo "$OUT" | grep -q 'Quit anyway'; then 41 echo "ok: children correctly allow ptrace" 42else 43 echo "FAIL: Children unexpectedly not allow ptrace" 44 rc=1 45fi 46 47# Check we can't see cousins. 48sleep 120 & 49pid=$! 50OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1) 51if echo "$OUT" | grep -q 'Operation not permitted'; then 52 echo "ok: cousins correctly not allow ptrace" 53else 54 echo "FAIL: cousins unexpectedly allow ptrace" 55 rc=1 56fi 57 58# Validate we can see cousin /proc entries. 59if ls -la /proc/$pid/exe >/dev/null 2>&1; then 60 echo "ok: cousins correctly visible in /proc" 61else 62 echo "FAIL: cousins unexpectedly invisible in /proc" 63 rc=1 64fi 65 66# Check we can't attach to init. 67OUT=$(gdb -ex "attach 1" -ex "quit" --batch </dev/null 2>&1) 68if echo "$OUT" | grep -q 'Operation not permitted'; then 69 echo "ok: init correctly not allowing ptrace" 70else 71 echo "FAIL: init unexpectedly allowed ptrace" 72 rc=1 73fi 74 75# Check we can't see init. 76if ! ls -la /proc/1/exe >/dev/null 2>&1; then 77 echo "ok: init correctly invisible in /proc" 78else 79 echo "FAIL: init unexpectedly visible in /proc" 80 rc=1 81fi 82 83# Drop the sleep process and destroy it without disrupting the shell. 84disown $pid 85kill $pid 86 87# Validate that prctl(PR_SET_PTRACER, 0, ...) works to delete tracer. 88start_sleeper 0 89OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1) 90prctl="prctl(PR_SET_PTRACER, 0, ...)" 91if echo "$OUT" | grep -q 'Operation not permitted'; then 92 echo "ok: $prctl correctly not allowed ptrace" 93else 94 echo "FAIL: $prctl unexpectedly allowed ptrace" 95 rc=1 96fi 97kill_sleeper 98 99# Validate near ancestor allowed with PR_SET_PTRACER use. 100start_sleeper $$ 101OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1) 102prctl="prctl(PR_SET_PTRACER, parent, ...)" 103if echo "$OUT" | grep -q 'Quit anyway'; then 104 echo "ok: $prctl correctly allowed ptrace" 105else 106 echo "FAIL: $prctl unexpectedly not allowed ptrace" 107 rc=1 108fi 109kill_sleeper 110 111# Validate distant ancestor allowed with PR_SET_PTRACER use. 112start_sleeper 1 113OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1) 114prctl="prctl(PR_SET_PTRACER, 1, ...)" 115if echo "$OUT" | grep -q 'Quit anyway'; then 116 echo "ok: $prctl correctly allowed ptrace" 117else 118 echo "FAIL: $prctl unexpectedly not allowed ptrace" 119 rc=1 120fi 121kill_sleeper 122 123# Validate -1 disables protection. 124start_sleeper -1 125OUT=$(gdb -ex "attach $pid" -ex "quit" --batch </dev/null 2>&1) 126prctl="prctl(PR_SET_PTRACER, -1, ...)" 127if echo "$OUT" | grep -q 'Quit anyway'; then 128 echo "ok: $prctl correctly allowed ptrace" 129else 130 echo "FAIL: $prctl unexpectedly not allowed ptrace" 131 rc=1 132fi 133kill_sleeper 134 135exit $rc 136