summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-03-28 16:51:11 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-03-30 18:39:46 +0200
commitbdc34d0383ffd80bc76b24619b26df29307243e0 (patch)
treed8a1a413fe78212d3e1c5a9ab90c50ce5389df30
Add libpinniped
-rw-r--r--README29
-rwxr-xr-xbin/pinniped6
-rw-r--r--libpinniped/Makefile28
-rw-r--r--libpinniped/pinniped.c64
-rw-r--r--libpinniped/test.c38
5 files changed, 165 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..74aab4a
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+portseal - tools to locate port management bugs
+===============================================
+
+This is a collection of tools to find bugs related to Mach port
+handling like port leaks at runtime.
+
+libpinniped
+-----------
+
+libpinniped wraps port manipulation functions (i.e. the glibc
+wrappers) with the help of the dynamic linker. If any of the wrapped
+functions fail, a message is written to stderr with a backtrace.
+
+% make -C libpinniped check
+make: Entering directory `.../portseal/libpinniped'
+LD_PRELOAD=./"libpinniped.so" ./test
+./test: mach_port_deallocate (1, 12345): (os/kern) invalid name
+./test(dosth+0x1b)[0x80486c8]
+./test(main+0xb)[0x80486f2]
+/lib/i386-gnu/libc.so.0.3(__libc_start_main+0xbc)[0x109169c]
+./test[0x80485d1]
+./test: mach_port_destroy (1, 54321): (os/kern) invalid name
+./test(dosthelse+0x1b)[0x80486e5]
+./test(main+0x10)[0x80486f7]
+/lib/i386-gnu/libc.so.0.3(__libc_start_main+0xbc)[0x109169c]
+./test[0x80485d1]
+make: Leaving directory `.../portseal/libpinniped'
+% addr2line -e libpinniped/test 0x80486c8
+.../portseal/libpinniped/test.c:24
diff --git a/bin/pinniped b/bin/pinniped
new file mode 100755
index 0000000..70b916f
--- /dev/null
+++ b/bin/pinniped
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+SCRIPT="`readlink -f $0`"
+LIBPINNIPED="`dirname $SCRIPT`/../libpinniped/libpinniped.so"
+
+exec /usr/bin/env LD_PRELOAD="$LIBPINNIPED $LD_PRELOAD" "$@"
diff --git a/libpinniped/Makefile b/libpinniped/Makefile
new file mode 100644
index 0000000..d867879
--- /dev/null
+++ b/libpinniped/Makefile
@@ -0,0 +1,28 @@
+# Copyright (c) 2014 Justus Winter <4winter@informatik.uni-hamburg.de>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+USE_PKG =
+
+CFLAGS = -Wall -ggdb \
+ $(foreach lib,$(USE_PKG),$(shell pkg-config --cflags $(lib)))
+LDFLAGS = -rdynamic -ldl \
+ $(foreach lib,$(USE_PKG),$(shell pkg-config --libs $(lib)))
+
+all: libpinniped.so
+
+check: libpinniped.so test
+ LD_PRELOAD=./"$<" ./test
+
+libpinniped.so: pinniped.o
+ gcc -shared -o "$@" "$<" -ldl
diff --git a/libpinniped/pinniped.c b/libpinniped/pinniped.c
new file mode 100644
index 0000000..348638f
--- /dev/null
+++ b/libpinniped/pinniped.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 Justus Winter <4winter@informatik.uni-hamburg.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <errno.h>
+#include <execinfo.h>
+#include <mach.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+static void
+print_backtrace (const char *f, ...)
+{
+ va_list args;
+
+ va_start (args, f);
+ vfprintf (stderr, f, args);
+ va_end (args);
+
+ void *array[20];
+ size_t size;
+ size = backtrace (array, 20);
+ backtrace_symbols_fd (&array[2], size - 2, 2);
+}
+
+#define wrap(NAME) \
+ kern_return_t \
+ NAME (ipc_space_t task, mach_port_t name) \
+ { \
+ static kern_return_t (*f)(ipc_space_t, mach_port_t) = NULL; \
+ if (! f) \
+ f = dlsym (RTLD_NEXT, #NAME); \
+ \
+ kern_return_t r = f (task, name); \
+ if (r != KERN_SUCCESS) \
+ { \
+ char buf[80]; \
+ print_backtrace ("%s: " #NAME " (%d, %d): %s\n", \
+ program_invocation_name, \
+ task, name, \
+ strerror_r (r, buf, sizeof buf)); \
+ } \
+ return r; \
+ }
+
+wrap (mach_port_deallocate)
+wrap (mach_port_destroy)
+
+#undef wrap
diff --git a/libpinniped/test.c b/libpinniped/test.c
new file mode 100644
index 0000000..b1f8939
--- /dev/null
+++ b/libpinniped/test.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Justus Winter <4winter@informatik.uni-hamburg.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define _GNU_SOURCE
+#include <mach.h>
+
+void
+dosth (void)
+{
+ mach_port_deallocate (mach_task_self (), 12345);
+}
+
+void
+dosthelse (void)
+{
+ mach_port_destroy (mach_task_self (), 54321);
+}
+
+int
+main ()
+{
+ dosth ();
+ dosthelse ();
+ return 0;
+}