Skip to content

Commit

Permalink
Merge pull request iovisor#2394 from kinvolk/kai/capable_hide_extra_f…
Browse files Browse the repository at this point in the history
…ields

capable: Hide TID and INSETID columns by default
  • Loading branch information
brendangregg committed Jun 5, 2019
2 parents d61f9ba + 721d34e commit e8dd701
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 36 deletions.
3 changes: 3 additions & 0 deletions man/man8/capable.8
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Include kernel stack traces to the output.
.TP
\-U
Include user-space stack traces to the output.
.TP
\-x
Show extra fields in TID and INSETID columns.
.SH EXAMPLES
.TP
Trace all capability checks system-wide:
Expand Down
22 changes: 17 additions & 5 deletions tools/capable.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
./capable -p 181 # only trace PID 181
./capable -K # add kernel stacks to trace
./capable -U # add user-space stacks to trace
./capable -x # extra fields: show TID and INSETID columns
"""
parser = argparse.ArgumentParser(
description="Trace security capability checks",
Expand All @@ -39,6 +40,8 @@
help="output kernel stack trace")
parser.add_argument("-U", "--user-stack", action="store_true",
help="output user stack trace")
parser.add_argument("-x", "--extra", action="store_true",
help="show extra fields in TID and INSETID columns")
args = parser.parse_args()
debug = 0

Expand Down Expand Up @@ -178,8 +181,12 @@ def __getattr__(self, name):
b = BPF(text=bpf_text)

# header
print("%-9s %-6s %-6s %-6s %-16s %-4s %-20s %-6s %s" % (
"TIME", "UID", "PID", "TID", "COMM", "CAP", "NAME", "AUDIT", "INSETID"))
if args.extra:
print("%-9s %-6s %-6s %-6s %-16s %-4s %-20s %-6s %s" % (
"TIME", "UID", "PID", "TID", "COMM", "CAP", "NAME", "AUDIT", "INSETID"))
else:
print("%-9s %-6s %-6s %-16s %-4s %-20s %-6s" % (
"TIME", "UID", "PID", "COMM", "CAP", "NAME", "AUDIT"))

def stack_id_err(stack_id):
# -EFAULT in get_stackid normally means the stack-trace is not availible,
Expand All @@ -203,9 +210,14 @@ def print_event(bpf, cpu, data, size):
name = capabilities[event.cap]
else:
name = "?"
print("%-9s %-6d %-6d %-6d %-16s %-4d %-20s %-6d %s" % (strftime("%H:%M:%S"),
event.uid, event.pid, event.tgid, event.comm.decode('utf-8', 'replace'),
event.cap, name, event.audit, str(event.insetid) if event.insetid != -1 else "N/A"))
if args.extra:
print("%-9s %-6d %-6d %-6d %-16s %-4d %-20s %-6d %s" % (strftime("%H:%M:%S"),
event.uid, event.pid, event.tgid, event.comm.decode('utf-8', 'replace'),
event.cap, name, event.audit, str(event.insetid) if event.insetid != -1 else "N/A"))
else:
print("%-9s %-6d %-6d %-16s %-4d %-20s %-6d" % (strftime("%H:%M:%S"),
event.uid, event.pid, event.comm.decode('utf-8', 'replace'),
event.cap, name, event.audit))
if args.kernel_stack:
print_stack(bpf, event.kernel_stack_id, StackType.Kernel, -1)
if args.user_stack:
Expand Down
67 changes: 36 additions & 31 deletions tools/capable_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,42 @@ capable traces calls to the kernel cap_capable() function, which does security
capability checks, and prints details for each call. For example:

# ./capable.py
TIME UID PID COMM CAP NAME AUDIT INSETID
22:11:23 114 2676 snmpd 12 CAP_NET_ADMIN 1 N/A
22:11:23 0 6990 run 24 CAP_SYS_RESOURCE 1 N/A
22:11:23 0 7003 chmod 3 CAP_FOWNER 1 N/A
22:11:23 0 7003 chmod 4 CAP_FSETID 1 N/A
22:11:23 0 7005 chmod 4 CAP_FSETID 1 N/A
22:11:23 0 7005 chmod 4 CAP_FSETID 1 N/A
22:11:23 0 7006 chown 4 CAP_FSETID 1 N/A
22:11:23 0 7006 chown 4 CAP_FSETID 1 N/A
22:11:23 0 6990 setuidgid 6 CAP_SETGID 1 N/A
22:11:23 0 6990 setuidgid 6 CAP_SETGID 1 N/A
22:11:23 0 6990 setuidgid 7 CAP_SETUID 1 N/A
22:11:24 0 7013 run 24 CAP_SYS_RESOURCE 1 N/A
22:11:24 0 7026 chmod 3 CAP_FOWNER 1 N/A
22:11:24 0 7026 chmod 4 CAP_FSETID 1 N/A
22:11:24 0 7028 chmod 4 CAP_FSETID 1 N/A
22:11:24 0 7028 chmod 4 CAP_FSETID 1 N/A
22:11:24 0 7029 chown 4 CAP_FSETID 1 N/A
22:11:24 0 7029 chown 4 CAP_FSETID 1 N/A
22:11:24 0 7013 setuidgid 6 CAP_SETGID 1 N/A
22:11:24 0 7013 setuidgid 6 CAP_SETGID 1 N/A
22:11:24 0 7013 setuidgid 7 CAP_SETUID 1 N/A
22:11:25 0 7036 run 24 CAP_SYS_RESOURCE 1 N/A
22:11:25 0 7049 chmod 3 CAP_FOWNER 1 N/A
22:11:25 0 7049 chmod 4 CAP_FSETID 1 N/A
22:11:25 0 7051 chmod 4 CAP_FSETID 1 N/A
22:11:25 0 7051 chmod 4 CAP_FSETID 1 N/A

A recent kernel version >= 5.1 also reports the INSETID bit to cap_capable():

# ./capable.py
TIME UID PID COMM CAP NAME AUDIT
22:11:23 114 2676 snmpd 12 CAP_NET_ADMIN 1
22:11:23 0 6990 run 24 CAP_SYS_RESOURCE 1
22:11:23 0 7003 chmod 3 CAP_FOWNER 1
22:11:23 0 7003 chmod 4 CAP_FSETID 1
22:11:23 0 7005 chmod 4 CAP_FSETID 1
22:11:23 0 7005 chmod 4 CAP_FSETID 1
22:11:23 0 7006 chown 4 CAP_FSETID 1
22:11:23 0 7006 chown 4 CAP_FSETID 1
22:11:23 0 6990 setuidgid 6 CAP_SETGID 1
22:11:23 0 6990 setuidgid 6 CAP_SETGID 1
22:11:23 0 6990 setuidgid 7 CAP_SETUID 1
22:11:24 0 7013 run 24 CAP_SYS_RESOURCE 1
22:11:24 0 7026 chmod 3 CAP_FOWNER 1
22:11:24 0 7026 chmod 4 CAP_FSETID 1
22:11:24 0 7028 chmod 4 CAP_FSETID 1
22:11:24 0 7028 chmod 4 CAP_FSETID 1
22:11:24 0 7029 chown 4 CAP_FSETID 1
22:11:24 0 7029 chown 4 CAP_FSETID 1
22:11:24 0 7013 setuidgid 6 CAP_SETGID 1
22:11:24 0 7013 setuidgid 6 CAP_SETGID 1
22:11:24 0 7013 setuidgid 7 CAP_SETUID 1
22:11:25 0 7036 run 24 CAP_SYS_RESOURCE 1
22:11:25 0 7049 chmod 3 CAP_FOWNER 1
22:11:25 0 7049 chmod 4 CAP_FSETID 1
22:11:25 0 7051 chmod 4 CAP_FSETID 1
22:11:25 0 7051 chmod 4 CAP_FSETID 1

Checks where AUDIT is 0 are ignored by default, which can be changed
with -v but is more verbose.

We can show the TID and INSETID columns with -x.
Since only a recent kernel version >= 5.1 reports the INSETID bit to cap_capable(),
the fallback value "N/A" will be displayed on older kernels.

# ./capable.py -x
TIME UID PID TID COMM CAP NAME AUDIT INSETID
08:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0
08:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0
Expand Down

0 comments on commit e8dd701

Please sign in to comment.