1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
#!/bin/bash
# Copyright 2010 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This utility finds the different processes in a running instance of Chrome.
# It then attempts to identify their types (e.g. browser, extension, plugin,
# zygote, renderer). It also prints out information on whether a sandbox is
# active and what type of sandbox has been identified.
# This script is likely to only work on Linux or systems that closely mimick
# Linux's /proc filesystem.
[ -x /proc/self/exe ] || {
echo "This script cannot be run on your system" >&2
exit 1
}
# Find the browser's process id. If there are multiple active instances of
# Chrome, the caller can provide a pid on the command line. The provided pid
# must match a process in the browser's process hierarchy. When using the
# zygote inside of the setuid sandbox, renderers are in a process tree separate
# from the browser process. You cannot use any of their pids.
# If no pid is provided on the command line, the script will randomly pick
# one of the running instances.
if [ $# -eq 0 ]; then
pid=$(ls -l /proc/*/exe 2>/dev/null |
sed '/\/chrome\( .deleted.\)\?$/s,.*/proc/\([^/]*\)/exe.*,\1,;t;d' |
while read p; do
xargs -0 </proc/$p/cmdline 2>/dev/null|grep -q -- --type= && continue
echo "$p"
break
done)
else
pid="$1"
fi
ls -l "/proc/$pid/exe" 2>/dev/null|egrep -q '/chrome( .deleted.)?$' || {
echo "Cannot find any running instance of Chrome" >&2; exit 1; }
while :; do
ppid="$(ps h --format ppid --pid "$pid" 2>/dev/null)"
[ -n "$ppid" ] || {
echo "Cannot find any running instance of Chrome" >&2; exit 1; }
ls -l "/proc/$ppid/exe" 2>/dev/null|egrep -q '/chrome( .deleted.)?$' &&
pid="$ppid" || break
done
xargs -0 </proc/$p/cmdline 2>/dev/null|grep -q -- --type= && {
echo "Cannot find any running instance of Chrome" >&2; exit 1; }
# Iterate over child processes and try to identify them
identify() {
local child cmd foundzygote plugin seccomp type
foundzygote=0
for child in $(ps h --format pid --ppid $1); do
cmd="$(xargs -0 </proc/$child/cmdline|sed 's/ -/\n-/g')" 2>/dev/null
type="$(echo "$cmd" | sed 's/--type=//;t1;d;:1;q')"
case $type in
'')
echo "Process $child is part of the browser"
identify "$child"
;;
extension)
echo "Process $child is an extension"
;;
plugin)
plugin="$(echo "$cmd" |
sed 's/--plugin-path=//;t1;d;:1
s,.*/lib,,;s,.*/npwrapper[.]lib,,;s,^np,,;s,[.]so$,,;q')"
echo "Process $child is a \"$plugin\" plugin"
identify "$child"
;;
renderer|worker|gpu-process)
# The seccomp sandbox has exactly one child process that has no other
# threads. This is the trusted helper process.
seccomp="$(ps h --format pid --ppid $child|xargs)"
if [ -d /proc/$child/cwd/. ]; then
if [ $(echo "$seccomp" | wc -w) -eq 1 ] &&
[ $(ls /proc/$seccomp/task 2>/dev/null | wc -w) -eq 1 ] &&
ls -l /proc/$seccomp/exe 2>/dev/null |
egrep -q '/chrome( .deleted.)?$'; then
echo "Process $child is a sandboxed $type (seccomp helper:" \
"$seccomp)"
else
echo "Process $child is a $type"
identify "$child"
fi
else
if [ $(echo "$seccomp" | wc -w) -eq 1 ]; then
echo "Process $child is a setuid sandboxed $type (seccomp" \
"helper: $seccomp)"
else
echo "Process $child is a $type; setuid sandbox is active"
identify "$child"
fi
fi
;;
zygote)
foundzygote=1
echo "Process $child is the zygote"
identify "$child"
;;
*)
echo "Process $child is of unknown type \"$type\""
identify "$child"
;;
esac
done
return $foundzygote
}
cmpcmdline() {
# Checks that the command line arguments for pid $1 are a superset of the
# commandline arguments for pid $2.
# Any additional function arguments $3, $4, ... list options that should
# be ignored for the purpose of this comparison.
local pida="$1"
local pidb="$2"
shift; shift
local super=("$@" $(xargs -0 </proc/"$pida"/cmdline)) 2>/dev/null
local sub=($(xargs -0 </proc/"$pidb"/cmdline)) 2>/dev/null
local i j
[ ${#sub[*]} -eq 0 -o ${#super[*]} -eq 0 ] && return 1
for i in $(seq 0 $((${#sub[*]}-1))); do
for j in $(seq 0 $((${#super[*]}-1))); do
[ "x${sub[$i]}" = "x${super[$j]}" ] && continue 2
done
return 1
done
return 0
}
echo "The browser's main pid is: $pid"
if identify "$pid"; then
# The zygote can make it difficult to locate renderers, as the setuid
# sandbox causes it to be reparented to "init". When this happens, we can
# no longer associate it with the browser with 100% certainty. We make a
# best effort by comparing command line strings.
for i in $(ps h --format pid --ppid 1); do
if cmpcmdline "$pid" "$i" "--type=zygote"; then
echo -n "Process $i is the zygote"
[ -d /proc/$i/cwd/. ] || echo -n "; setuid sandbox is active"
echo
identify "$i"
fi
done
fi
|