1#!/bin/bash
2# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5set -e
6if [ "$(whoami)" != "root" ]; then
7    echo "Must be root for this test" >&2
8    exit 1
9fi
10NONROOT="$1"
11
12export LANG=C
13pid=
14dir=
15
16function start_sleeper()
17{
18    dir=$(mktemp -d -t sleeper-XXXXXX)
19    mkfifo "$dir"/status
20    minijail0 -p -- ./inside-pidns.sh "$1" $NONROOT >"$dir"/status &
21    pid=$!
22    # Immediately forget about minijail process. We will find sleeper next.
23    disown $pid
24    # Wait for sleeper to start up.
25    read status < "$dir"/status
26    # Find sleeper pid.
27    while [ $(ps -p $pid -o comm=) != "sleeper" ]; do
28        pid=$(ps -ef | awk '{ if ($3 == '"$pid"') { print $2 }}')
29        if [ -z "$pid" ]; then
30            echo "Failed to locate pidns sleeper." >&2
31            exit 1
32        fi
33    done
34}
35
36function kill_sleeper()
37{
38    kill $pid
39    rm -rf "$dir"
40}
41
42rc=0
43
44# Validate that prctl(PR_SET_PTRACER, 0, ...) cannot be ptraced across pidns.
45start_sleeper 0
46OUT=$(su -c 'gdb -ex "attach '"$pid"'" -ex "quit" --batch' $NONROOT \
47        </dev/null 2>&1)
48prctl="prctl(PR_SET_PTRACER, 0, ...)"
49if echo "$OUT" | grep -q 'Operation not permitted'; then
50    echo "ok: $prctl correctly not allowed ptrace"
51else
52    echo "FAIL: $prctl unexpectedly allowed ptrace"
53    rc=1
54fi
55kill_sleeper
56
57# Validate that prctl(PR_SET_PTRACER, -1, ...) can be ptraced across pidns.
58start_sleeper -1
59OUT=$(su -c 'gdb -ex "attach '"$pid"'" -ex "quit" --batch' $NONROOT \
60        </dev/null 2>&1)
61prctl="prctl(PR_SET_PTRACER, -1, ...)"
62if echo "$OUT" | grep -q 'Quit anyway'; then
63    echo "ok: $prctl correctly allowed ptrace"
64else
65    echo "FAIL: $prctl unexpectedly not allowed ptrace"
66    rc=1
67fi
68kill_sleeper
69
70exit $rc
71