From bdc34d0383ffd80bc76b24619b26df29307243e0 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 28 Mar 2014 16:51:11 +0100 Subject: Add libpinniped --- README | 29 +++++++++++++++++++++++ bin/pinniped | 6 +++++ libpinniped/Makefile | 28 ++++++++++++++++++++++ libpinniped/pinniped.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ libpinniped/test.c | 38 ++++++++++++++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 README create mode 100755 bin/pinniped create mode 100644 libpinniped/Makefile create mode 100644 libpinniped/pinniped.c create mode 100644 libpinniped/test.c 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 +#include +#include +#include +#include +#include +#include + +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 + +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; +} -- cgit v1.2.3