Skip to content

Instantly share code, notes, and snippets.

@bbhoss
Created January 21, 2015 17:43
Show Gist options
  • Save bbhoss/6825be67b2c8a7ad0081 to your computer and use it in GitHub Desktop.
Save bbhoss/6825be67b2c8a7ad0081 to your computer and use it in GitHub Desktop.
Debug privileges of a process on Solaris/Illumos. Rescued from Wayback Machine
#!/usr/bin/perl
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2006 Sun Microsystems Inc. All rights reserved.
# Use is subject to license terms.
#
# Some concepts in this script have been cribed from the scripts in the
# DTracetoolkit by Brendan Gregg: http://users.tpg.com.au/adsln4yb/dtrace.html
use Getopt::Std;
use Sun::Solaris::Privilege qw(:ALL);
&Usage() if $ARGV[0] eq "--help";
getopts('He:fhn:o:p:vz:') || &Usage();
&Usage() if $opt_h;
$FILTER = "";
$COMMAND= 0;
if ($opt_e) {
$COMMAND= 1 if defined $opt_e;
$FILTER = "(pid == \$target)";
} else {
$FILTER = "(execname == \"$opt_n\")" if defined $opt_n;
if ($FILTER) {
$FILTER = "$FILTER && (pid == $opt_p)" if defined $opt_p;
} else {
$FILTER = "(pid == $opt_p)" if defined $opt_p;
}
if ($FILTER) {
$FILTER = "$FILTER && (zonename == \"$opt_z\")"
if defined $opt_z;
} else {
$FILTER = "(zonename == \"$opt_z\")" if defined $opt_z;
}
&Usage if not $FILTER;
}
$FOLLOW = 0;
$FOLLOW = 1 if defined $opt_f;
$HEADER = 1;
$HEADER = 0 if defined $opt_H;
$VERBOSE = 0;
$VERBOSE = 1 if defined $opt_v;
$dscript = <<END;
#pragma D option quiet
BEGIN {
trackedpid[pid] = 0;
self->child = 0;
}
syscall:::entry
/($FILTER) || self->child/
{
self->start = timestamp;
}
/* Follow children */
syscall::fork*:entry
/$FOLLOW && self->start/
{
/* track this parent process */
trackedpid[pid] = 1;
}
syscall::fork*:return
/$FOLLOW && trackedpid[ppid]/
{
/* set as child */
self->child = 1;
}
sdt:::priv-ok
/($FILTER) || self->child/
{
printf("USED:%d:%d:%d:%s:%d:%d\\n", pid, ppid,
uid, execname, timestamp, arg0);
}
sdt:::priv-err
/($FILTER) || self->child/
{
printf("NEED:%d:%d:%d:%s:%d:%d\\n", pid, ppid,
uid, execname, timestamp, arg0);
}
END
$SIG{INT} = \&Cleanup_Signal; # Ctrl-C
$SIG{QUIT} = \&Cleanup_Signal; # Ctrl-\
$SIG{TERM} = \&Cleanup_Signal; # TERM
$dtrace = "/usr/sbin/dtrace -n '$dscript'";
if ($COMMAND) {
$dtrace = $dtrace . " -c \"$opt_e\"";
}
open(DTRACE, "$dtrace |") || die "failed to start dtrace\n";
if ($opt_o) {
open(OUTPUT, ">", "$opt_o") || die "open of $opt_e failed: $!";
} else {
open(OUTPUT, ">&1") || die "can't dup stdout";
}
if ($HEADER) {
if ($VERBOSE) {
printf(OUTPUT "%-4s %-18s %-6s %-6s %-6s %-20s %s\n",
"STAT", "TIMESTAMP", "PPID", "PID", "UID",
"PRIV", "CMD");
} else {
printf(OUTPUT "%-4s %s\n", "STAT", "PRIV");
}
}
while (chomp($line = <DTRACE>)) {
($need, $ppid, $pid, $uid, $execname, $time, $privnum) = split(':', $line);
if ($need) {
if ($VERBOSE) {
printf(OUTPUT "%-4s %-18s %-6s %-6s %-6s %-20s %s\n",
$need, $time, $pid, $ppid, $uid,
priv_getbynum($privnum), $execname);
} else {
printf(OUTPUT "%-4s %s\n", $need, priv_getbynum($privnum));
}
}
}
close(DTRACE);
close(OUTPUT) if defined $opt_o;
sub Cleanup_Signal {
}
sub Usage {
printf(STDERR "privdebug [-f] [-v] [-H] [-o out]\n");
printf(STDERR " %-15s\t%s", "-n <EXECNAME>",
"Debug a specific program name\n");
printf(STDERR " %-15s\t%s", "-p <PID>",
"Debug a specific process ID\n");
printf(STDERR " %-15s\t%s", "-z <ZONENAME>",
"Debug a specific zone name\n");
printf(STDERR "\nprivdebug [-f] [-v] [-H] [-o out]\n");
printf(STDERR " %-15s\t%s", "-e <COMMAND>",
"Execute and debug a specific command\n");
printf(STDERR "\nprivdebug --help | -h\n");
exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment