From e35184adda272d98bdc52ac5bef401207d2408c2 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Sat, 10 Nov 2012 08:22:01 -0500 Subject: [PATCH] Disable optimizing of memset() during compilation. But try to keep other user CFLAGS --- configure.ac | 10 ++++ src/Makefile.am | 10 +++- src/libpwmd.c | 15 +++++- src/mem.c | 154 ++++++++++++++++++++++++++++++++++++++++++-------------- src/mem.h | 31 ++++++------ src/memzero.c | 40 +++++++++++++++ src/memzero.h | 25 +++++++++ 7 files changed, 227 insertions(+), 58 deletions(-) create mode 100644 src/memzero.c create mode 100644 src/memzero.h diff --git a/configure.ac b/configure.ac index caaa8c2b..18f7f8e3 100644 --- a/configure.ac +++ b/configure.ac @@ -237,6 +237,16 @@ AC_ARG_WITH(crackdict, AC_HELP_STRING([--with-crack-dict=PATH], AC_SUBST(crackdict) AC_DEFINE_UNQUOTED(CRACKLIB_DICT, ["$crackdict"], [The location of the cracklib dictionary.]) +dnl Disable optimizing of memset(). GCC and CLang (and others?) accept +dnl multiple optimization flags and use the last one specified. The +dnl non-optimized memset() may still use any CPU features found in the +dnl user specified CFLAGS (-mtune) and libc. +CFLAGS_ORIG="$CFLAGS" +CFLAGS_MEMZERO="$CFLAGS -O0" +CFLAGS= +AC_SUBST(CFLAGS_ORIG) +AC_SUBST(CFLAGS_MEMZERO) + AC_CONFIG_FILES([Makefile libpwmd-7.0.pc doc/Makefile doc/doxygen.conf.in \ doc/pwmc.1 src/Makefile src/libpwmd.h po/Makefile.in]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 304fb0f6..24d70756 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,9 @@ DEFAULT_INCLUDES = -I. -I$(top_builddir) +noinst_LTLIBRARIES = libmemzero.la +libmemzero_la_SOURCES = memzero.c memzero.h +libmemzero_la_CFLAGS = @CFLAGS_MEMZERO@ + lib_LTLIBRARIES = libpwmd.la libpwmd_ladir = $(includedir) libpwmd_la_SOURCES = libpwmd.c libpwmd.h types.h gettext.h mem.h misc.c misc.h @@ -8,7 +12,8 @@ libpwmd_la_LDFLAGS = -version-info @VER_MAJOR@:@VER_PATCH@:@VER_MINOR@ \ @PTHREAD_LIBS@ @GPG_ERROR_LIBS@ @LTLIBINTL@ \ @LIBASSUAN_LIBS@ libpwmd_la_CFLAGS = -DLOCALEDIR=\"${prefix}/share/locale\" @GPG_ERROR_CFLAGS@ \ - @PTHREAD_CFLAGS@ @LIBASSUAN_CFLAGS@ + @PTHREAD_CFLAGS@ @LIBASSUAN_CFLAGS@ @CFLAGS_ORIG@ +libpwmd_la_LIBADD = libmemzero.la if WITH_SSH libpwmd_la_SOURCES += ssh.c ssh.h @@ -35,7 +40,8 @@ pwmc_SOURCES = pwmc.c if NEED_GETOPT_LONG pwmc_SOURCES += getopt_long.c getopt_long.h endif -pwmc_CFLAGS = -DLOCALEDIR=\"${prefix}/share/locale\" @GPG_ERROR_CFLAGS@ +pwmc_CFLAGS = -DLOCALEDIR=\"${prefix}/share/locale\" @GPG_ERROR_CFLAGS@ \ + @CFLAGS_ORIG@ pwmc_LDFLAGS = @GPG_ERROR_LIBS@ pwmc_LDADD= -lpwmd pwmc_DEPENDENCIES= libpwmd.la diff --git a/src/libpwmd.c b/src/libpwmd.c index 857f2627..f6047896 100644 --- a/src/libpwmd.c +++ b/src/libpwmd.c @@ -1435,7 +1435,20 @@ void *pwmd_realloc(void *ptr, size_t size) char *pwmd_strdup(const char *str) { - return _xstrdup(str); + char *t; + size_t len; + register size_t c; + + len = strlen(str); + t = _xmalloc((len+1)*sizeof(char)); + if (!t) + return NULL; + + for (c = 0; c < len; c++) + t[c] = str[c]; + + t[c] = 0; + return t; } char *pwmd_strdup_printf(const char *fmt, ...) diff --git a/src/mem.c b/src/mem.c index 9ae3dde1..729aa27c 100644 --- a/src/mem.c +++ b/src/mem.c @@ -27,15 +27,60 @@ #include #include #include -#include +#include "memzero.h" + +#ifndef _ #include "gettext.h" -#define N_(msgid) gettext(msgid) +#define _(msgid) gettext(msgid) +#endif + +#ifdef DEBUG +#ifdef HAVE_BACKTRACE +#include + +#ifndef BACKTRACE +#define BACKTRACE(fn) { \ + int n, nptrs; \ + char **strings; \ + void *buffer[20]; \ + nptrs = backtrace(buffer, 20); \ + strings = backtrace_symbols(buffer, nptrs); \ + for (n = 0; n < nptrs; n++) \ + fprintf(stderr, "BACKTRACE (%s) %i: %s\n", fn, n, strings[n]); \ + fprintf(stderr, "\n"); \ + fflush(stderr); \ + } +#endif +#endif +#else +#define BACKTRACE(fn) +#endif #include "mem.h" +#ifdef USE_PTH_THREADS +#include +#else +#include +#endif + +#ifndef _ +#define _ gettext(msgid) +#endif + +struct memlist_s { + void *ptr; + size_t size; + struct memlist_s *next; +}; + static struct memlist_s *memlist; +#ifdef USE_PTH_THREADS +static pth_mutex_t mem_mutex; +#else static pthread_mutex_t mem_mutex; +#endif #ifdef DEBUG static size_t allocations, deallocations; #endif @@ -45,7 +90,11 @@ void _xmem_init() static int init; if (!init) +#ifdef USE_PTH_THREADS + pth_mutex_init(&mem_mutex); +#else pthread_mutex_init(&mem_mutex, NULL); +#endif init = 1; } @@ -54,14 +103,18 @@ static int memlist_remove(void *ptr, const char *func) { struct memlist_s *m, *last = NULL, *p; +#ifdef USE_PTH_THREADS + pth_mutex_acquire(&mem_mutex, 0, NULL); +#else pthread_mutex_lock(&mem_mutex); +#endif for (m = memlist; m; m = m->next) { if (m->ptr == ptr) { #ifdef DEBUG fprintf(stderr, "%s: %p %i\n", func, ptr, m->size); #endif - memset(m->ptr, 0, m->size); + memzero(m->ptr, m->size); free(m->ptr); p = m->next; @@ -75,26 +128,42 @@ static int memlist_remove(void *ptr, const char *func) else memlist = p; +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif return 1; } last = m; } +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif return 0; } static void memlist_prepend(struct memlist_s *new) { +#ifdef USE_PTH_THREADS + pth_mutex_acquire(&mem_mutex, 0, NULL); +#else pthread_mutex_lock(&mem_mutex); +#endif #ifdef DEBUG allocations++; #endif new->next = memlist; memlist = new; +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif } void _xfree(void *ptr) @@ -103,7 +172,7 @@ void _xfree(void *ptr) return; if (!memlist_remove(ptr, __FUNCTION__)) { - warnx(N_("%s: %p not found"), __FUNCTION__, ptr); + warnx(_("%s: %p not found"), __FUNCTION__, ptr); assert(0); } } @@ -113,9 +182,6 @@ void *_xmalloc(size_t size) void *p; struct memlist_s *m; - if (size <= 0) - return NULL; - if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL) return NULL; @@ -129,6 +195,7 @@ void *_xmalloc(size_t size) memlist_prepend(m); #ifdef DEBUG fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size); + BACKTRACE(__FUNCTION__); #endif return m->ptr; } @@ -138,9 +205,6 @@ void *_xcalloc(size_t nmemb, size_t size) void *p; struct memlist_s *m; - if (size <= 0) - return NULL; - if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL) return NULL; @@ -154,6 +218,7 @@ void *_xcalloc(size_t nmemb, size_t size) memlist_prepend(m); #ifdef DEBUG fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, nmemb * size); + BACKTRACE(__FUNCTION__); #endif return m->ptr; } @@ -163,83 +228,90 @@ void *_xrealloc(void *ptr, size_t size) void *p; struct memlist_s *m; - if (size <= 0) - return ptr; + if (!size && ptr) { + _xfree(ptr); + return NULL; + } if (!ptr) return _xmalloc(size); +#ifdef USE_PTH_THREADS + pth_mutex_acquire(&mem_mutex, 0, NULL); +#else pthread_mutex_lock(&mem_mutex); +#endif for (m = memlist; m; m = m->next) { if (m->ptr == ptr) { if ((p = (void *)malloc(size)) == NULL) { +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif return NULL; } memcpy(p, m->ptr, size < m->size ? size : m->size); - memset(m->ptr, 0, m->size); + memzero(m->ptr, m->size); free(m->ptr); m->ptr = p; m->size = size; #ifdef DEBUG fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size); + BACKTRACE(__FUNCTION__); #endif +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif return m->ptr; } } - warnx(N_("%s: %p not found"), __FUNCTION__, ptr); + warnx(_("%s: %p not found"), __FUNCTION__, ptr); +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif assert(0); return NULL; } -char *_xstrdup(const char *str) -{ - char *t, *tp; - size_t len; - const char *p; - - if (!str) - return NULL; - - len = strlen(str) + 1; - - if ((t = (char *)_xmalloc(len * sizeof(char))) == NULL) - return NULL; - - for (p = str, tp = t; *p; p++) - *tp++ = *p; - - *tp = 0; -#ifdef DEBUG - fprintf(stderr, "%s: %p\n", __FUNCTION__, t); -#endif - return t; -} - void _xpanic(void) { struct memlist_s *m; +#ifdef USE_PTH_THREADS + pth_mutex_acquire(&mem_mutex, 0, NULL); +#else pthread_mutex_lock(&mem_mutex); +#endif for (m = memlist; m; m = memlist) _xfree(m->ptr); +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif } #ifdef DEBUG -void _xdump(void) +void xdump(void) { struct memlist_s *m; size_t total = 0; +#ifdef USE_PTH_THREADS + pth_mutex_acquire(&mem_mutex, 0, NULL); +#else pthread_mutex_lock(&mem_mutex); +#endif for (m = memlist; m; m = m->next) { fprintf(stderr, "%s: %p %i\n", __FUNCTION__, m->ptr, m->size); @@ -248,6 +320,10 @@ void _xdump(void) fprintf(stderr, "Total unfreed: %i bytes, allocations: %i, deallocations: %i\n", total, allocations, deallocations); +#ifdef USE_PTH_THREADS + pth_mutex_release(&mem_mutex); +#else pthread_mutex_unlock(&mem_mutex); +#endif } #endif diff --git a/src/mem.h b/src/mem.h index 17ffa6f5..34cfb99e 100644 --- a/src/mem.h +++ b/src/mem.h @@ -24,29 +24,28 @@ extern "C" { #endif +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + #ifdef MEM_DEBUG #define _xfree free #define _xmalloc malloc #define _xrealloc realloc #define _xcalloc calloc -#define _xstrdup strdup +#define _str_dup strdup #else -struct memlist_s { - void *ptr; - size_t size; - struct memlist_s *next; -}; - -void _xmem_init(void); -void _xfree(void *ptr); -void *_xmalloc(size_t size); -void *_xrealloc(void *ptr, size_t size); -char *_xstrdup(const char *str); -void *_xcalloc(size_t nmemb, size_t size); -void _xpanic(void); - +void _xmem_init(void) __attribute__ ((visibility ("hidden"))); +void _xfree(void *ptr) __attribute__ ((visibility ("hidden"))); +void *_xmalloc(size_t size) __attribute__ ((visibility ("hidden"))); +void *_xrealloc(void *ptr, size_t size) __attribute__ ((visibility ("hidden"))); +void *_xcalloc(size_t nmemb, size_t size) __attribute__ ((visibility ("hidden"))); +void _xpanic(void) __attribute__ ((visibility ("hidden"))); #ifdef DEBUG -void _xdump(void); +void _xdump(void) __attribute__ ((visibility ("hidden"))); #endif #endif diff --git a/src/memzero.c b/src/memzero.c new file mode 100644 index 00000000..a8350744 --- /dev/null +++ b/src/memzero.c @@ -0,0 +1,40 @@ +/* + Copyright (C) 2012 + Ben Kibbey + + This file is part of pwmd. + + Pwmd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Pwmd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Pwmd. If not, see . +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "memzero.h" + +void memzero(void *ptr, size_t size) +{ +#ifdef HAVE_MEMSET + (void)memset(ptr, 0, size); +#else + size_t n = size; + volatile char *p = (volatile char *)ptr; + + while (n) { + *p++ = 0; + n--; + } +#endif +} diff --git a/src/memzero.h b/src/memzero.h new file mode 100644 index 00000000..3801d4a6 --- /dev/null +++ b/src/memzero.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2012 + Ben Kibbey + + This file is part of pwmd. + + Pwmd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Pwmd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Pwmd. If not, see . +*/ +#ifndef MEMZERO_H +#define MEMZERO_H + +void memzero(void *ptr, size_t size); + +#endif -- 2.11.4.GIT