From c1b41c7ae5ffe104d7903cf53a195ae8f5daa30e827122bd9af8b24763798f40 Mon Sep 17 00:00:00 2001 From: Daniel Rahn Date: Mon, 20 Jun 2011 06:27:58 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/security:Stunnel/stunnel?expand=0&rev=43 --- fix-ucontext-handling.patch | 344 ++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) diff --git a/fix-ucontext-handling.patch b/fix-ucontext-handling.patch index f71024d..b4500b1 100644 --- a/fix-ucontext-handling.patch +++ b/fix-ucontext-handling.patch @@ -439,3 +439,347 @@ closesocket(s); /* don't care about the result */ #else if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "socketpair")) +--- src/str.c 2011-05-02 19:14:53.000000000 +0200 ++++ src/str.c 2011-05-08 08:37:57.000000000 +0200 +@@ -38,17 +38,128 @@ + #include "common.h" + #include "prototypes.h" + +-typedef struct str_struct { +- struct str_struct *prev, *next; ++#ifndef va_copy ++#ifdef __va_copy ++#define va_copy(dst, src) __va_copy((dst), (src)) ++#else /* __va_copy */ ++#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) ++#endif /* __va_copy */ ++#endif /* va_copy */ ++ ++typedef struct alloc_list { ++ struct alloc_list *prev, *next; + size_t size; + unsigned int magic; +-} STR; +-static void str_set(STR *); +-static STR *str_get(); ++} ALLOC_LIST; ++ ++static void set_alloc_head(ALLOC_LIST *); ++static ALLOC_LIST *get_alloc_head(); ++ ++char *str_dup(const char *str) { ++ char *retval; ++ ++ retval=str_alloc(strlen(str)+1); ++ if(retval) ++ strcpy(retval, str); ++ return retval; ++} ++ ++char *str_printf(const char *format, ...) { ++ char *txt; ++ va_list arglist; ++ ++ va_start(arglist, format); ++ txt=str_vprintf(format, arglist); ++ va_end(arglist); ++ return txt; ++} ++ ++char *str_vprintf(const char *format, va_list start_ap) { ++ int n, size=64; ++ char *p, *np; ++ va_list ap; ++ ++ p=str_alloc(size); ++ if(!p) ++ return NULL; ++ for(;;) { ++ va_copy(ap, start_ap); ++ n=vsnprintf(p, size, format, ap); ++ if(n>-1 && n-1) /* glibc 2.1 */ ++ size=n+1; /* precisely what is needed */ ++ else /* glibc 2.0, WIN32, etc. */ ++ size*=2; /* twice the old size */ ++ np=str_realloc(p, size); ++ if(!np) { ++ str_free(p); ++ return NULL; ++ } ++ p=np; /* LOL */ ++ } ++} ++ ++#ifdef USE_UCONTEXT ++ ++static ALLOC_LIST *alloc_tls=NULL; ++ ++void str_init() { ++} ++ ++static void set_alloc_head(ALLOC_LIST *alloc_head) { ++ if(ready_head) ++ ready_head->tls=alloc_head; ++ else /* ucontext threads not initialized */ ++ alloc_tls=alloc_head; ++} ++ ++static ALLOC_LIST *get_alloc_head() { ++ if(ready_head) ++ return ready_head->tls; ++ else /* ucontext threads not initialized */ ++ return alloc_tls; ++} ++ ++#endif /* USE_UCONTEXT */ ++ ++#ifdef USE_FORK ++ ++static ALLOC_LIST *alloc_tls=NULL; ++ ++void str_init() { ++} ++ ++static void set_alloc_head(ALLOC_LIST *alloc_head) { ++ alloc_tls=alloc_head; ++} ++ ++static ALLOC_LIST *get_alloc_head() { ++ return alloc_tls; ++} ++ ++#endif /* USE_FORK */ ++ ++#ifdef USE_PTHREAD ++ ++static pthread_key_t pthread_key; ++ ++void str_init() { ++ pthread_key_create(&pthread_key, NULL); ++} ++ ++static void set_alloc_head(ALLOC_LIST *alloc_head) { ++ pthread_setspecific(pthread_key, alloc_head); ++} ++ ++static ALLOC_LIST *get_alloc_head() { ++ return pthread_getspecific(pthread_key); ++} ++ ++#endif /* USE_PTHREAD */ + + #ifdef USE_WIN32 + +-/* __thread does not work in mingw32 due to a bug in GCC */ + static DWORD tls_index; + + void str_init() { +@@ -59,97 +170,81 @@ + } + } + +-static void str_set(STR *str) { +- if(!TlsSetValue(tls_index, str)) { ++static void set_alloc_head(ALLOC_LIST *alloc_head) { ++ if(!TlsSetValue(tls_index, alloc_head)) { + s_log(LOG_ERR, "TlsSetValue failed"); + die(1); + } + } + +-static STR *str_get() { +- STR *str; ++static ALLOC_LIST *get_alloc_head() { ++ ALLOC_LIST *alloc_head; + +- str=TlsGetValue(tls_index); +- if(!str && GetLastError()!=ERROR_SUCCESS) { ++ alloc_head=TlsGetValue(tls_index); ++ if(!alloc_head && GetLastError()!=ERROR_SUCCESS) { + s_log(LOG_ERR, "TlsGetValue failed"); + die(1); + } +- return str; +-} +- +-#else +- +-/* gcc Thread-Local Storage */ +-static __thread STR *root_str=NULL; +- +-void str_init() { +- if(root_str) +- s_log(LOG_WARNING, "str_init: Non-empty allocation list"); ++ return alloc_head; + } + +-static void str_set(STR *str) { +- root_str=str; +-} +- +-static STR *str_get() { +- return root_str; +-} +- +-#endif ++#endif /* USE_WIN32 */ + + void str_cleanup() { +- STR *str, *tmp; ++ ALLOC_LIST *alloc_head, *tmp; + +- str=str_get(); +- while(str) { +- tmp=str; +- str=tmp->next; ++ alloc_head=get_alloc_head(); ++ while(alloc_head) { ++ tmp=alloc_head; ++ alloc_head=tmp->next; + free(tmp); + } +- str_set(NULL); ++ set_alloc_head(NULL); + } + + void str_stats() { +- STR *tmp; ++ ALLOC_LIST *tmp; + int blocks=0, bytes=0; + +- for(tmp=str_get(); tmp; tmp=tmp->next) { ++ for(tmp=get_alloc_head(); tmp; tmp=tmp->next) { + ++blocks; + bytes+=tmp->size; + } +- s_log(LOG_DEBUG, "str_stats: %d blocks, %d bytes", blocks, bytes); ++ s_log(LOG_DEBUG, "str_stats: %d block(s), %d byte(s)", blocks, bytes); + } + + void *str_alloc(size_t size) { +- STR *str, *tmp; ++ ALLOC_LIST *alloc_head, *tmp; + + if(size>=1024*1024) /* huge allocations are not allowed */ + return NULL; +- tmp=calloc(1, sizeof(STR)+size); ++ tmp=calloc(1, sizeof(ALLOC_LIST)+size); + if(!tmp) + return NULL; +- str=str_get(); ++ alloc_head=get_alloc_head(); + tmp->prev=NULL; +- tmp->next=str; ++ tmp->next=alloc_head; + tmp->size=size; + tmp->magic=0xdeadbeef; +- if(str) +- str->prev=tmp; +- str_set(tmp); ++ if(alloc_head) ++ alloc_head->prev=tmp; ++ set_alloc_head(tmp); + return tmp+1; + } + + void *str_realloc(void *ptr, size_t size) { +- STR *oldtmp, *tmp; ++ ALLOC_LIST *old_tmp, *tmp; + + if(!ptr) + return str_alloc(size); +- oldtmp=(STR *)ptr-1; +- if(oldtmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ ++ old_tmp=(ALLOC_LIST *)ptr-1; ++ if(old_tmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ + s_log(LOG_CRIT, "INTERNAL ERROR: str_realloc: Bad magic"); + die(1); + } +- tmp=realloc(oldtmp, sizeof(STR)+size); ++ if(size>=1024*1024) /* huge allocations are not allowed */ ++ return NULL; ++ tmp=realloc(old_tmp, sizeof(ALLOC_LIST)+size); + if(!tmp) + return NULL; + /* refresh all possibly invalidated pointers */ +@@ -158,17 +253,17 @@ + if(tmp->prev) + tmp->prev->next=tmp; + tmp->size=size; +- if(str_get()==oldtmp) +- str_set(tmp); ++ if(get_alloc_head()==old_tmp) ++ set_alloc_head(tmp); + return tmp+1; + } + + void str_free(void *ptr) { +- STR *tmp; ++ ALLOC_LIST *tmp; + + if(!ptr) /* do not attempt to free null pointers */ + return; +- tmp=(STR *)ptr-1; ++ tmp=(ALLOC_LIST *)ptr-1; + if(tmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ + s_log(LOG_CRIT, "INTERNAL ERROR: str_free: Bad magic"); + die(1); +@@ -178,54 +273,9 @@ + tmp->next->prev=tmp->prev; + if(tmp->prev) + tmp->prev->next=tmp->next; +- if(str_get()==tmp) +- str_set(tmp->next); ++ if(get_alloc_head()==tmp) ++ set_alloc_head(tmp->next); + free(tmp); + } + +-char *str_dup(const char *str) { +- char *retval; +- +- retval=str_alloc(strlen(str)+1); +- if(retval) +- strcpy(retval, str); +- return retval; +-} +- +-char *str_vprintf(const char *format, va_list start_ap) { +- int n, size=64; +- char *p, *np; +- va_list ap; +- +- p=str_alloc(size); +- if(!p) +- return NULL; +- for(;;) { +- va_copy(ap, start_ap); +- n=vsnprintf(p, size, format, ap); +- if(n>-1 && n-1) /* glibc 2.1 */ +- size=n+1; /* precisely what is needed */ +- else /* glibc 2.0 */ +- size*=2; /* twice the old size */ +- np=str_realloc(p, size); +- if(!np) { +- str_free(p); +- return NULL; +- } +- p=np; /* LOL */ +- } +-} +- +-char *str_printf(const char *format, ...) { +- char *txt; +- va_list arglist; +- +- va_start(arglist, format); +- txt=str_vprintf(format, arglist); +- va_end(arglist); +- return txt; +-} +- + /* end of str.c */