123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #!/bin/bash
- # Copyright (c) 2010 The Chromium Authors. All rights reserved.
- # 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
|