1 From: Goswin Brederlow <goswin.brederlow@student.uni-tuebingen.de>
2 Subject: Bug#129345: patch to prevent a loop between libdl and libsafe causing libdl to crash
3 To: 129345@bugs.debian.org
4 Date: 01 Sep 2002 23:54:35 +0200
5 Reply-To: Goswin Brederlow <goswin.brederlow@student.uni-tuebingen.de>,
7 Resent-From: Goswin Brederlow <goswin.brederlow@student.uni-tuebingen.de>
11 [D. Coe edited this patch slightly -- moved an unrelated change into the
12 Makefile itself [it changed the debugging comments only], and corrected a
13 spelling error and reworded the comments. The original patch is in the
14 bug tracking system, if you want to see it as submitted by Goswin.]
17 D. Coe subsequently modified the patch further, because in some cases
18 the initializations did not occur (e.g. when IO_vfscanf or memcpy was
19 called from ps or top (likely one of the libraries they use). maybe
20 they do something that disables libsafe's library globals initialization?
23 In any case, I've adopted both strategise in this new patch; the addresses
24 are preloaded as Goswin had coded, but they are also individually checked
25 each time needed (as was the case before Goswin's patch), and are initialized
26 at that point if necessary. Hopefully this will let ps and top work
27 and also continue to work around the libdl problem.
32 if libsafe is invoked from inside libdl (or only inside dlerror()?)
33 and a real_XXX function is not yet looked up it will reenter
34 libdl. That causes memory corruption resulting in a read from 0x0 and
37 The patch below makes libsafe cache all needed symbols once upon
38 init. That not only causes less lookups than before but should prevent
39 fatal loops. Failures of the initial lookups might not be reported
40 correctly but terminate in some odd way if the functions needed to
41 report are not yet looked up.
46 ----------------------------------------------------------------------
47 diff -Nurd libsafe-2.0-16/src/intercept.c libsafe-2.0-16-mrvn/src/intercept.c
48 --- libsafe-2.0-16/src/intercept.c 2002-05-31 19:37:34.000000000 +0200
49 +++ libsafe-2.0-16-mrvn/src/intercept.c 2002-09-01 23:44:55.000000000 +0200
54 -/* Starting with version 2.0, we keep a single global copy of the pointer to
55 - * the real memcpy() function. This allows us to call
56 - * getLibraryFunction("memcpy") just once instead of multiple times, since
57 - * memcpy() is needed in four different functions below.
58 +/* Starting with Debian version 2.0-16-2, we keep a global copy of the pointer
59 + * to each real functions. Otherwise a getLibraryFunction might
60 + * be triggered from inside dlsym() and cause memory corruption reulting in a
63 -static memcpy_t real_memcpy = NULL;
66 +static memcpy_t real_memcpy = NULL;
67 +static _IO_vfscanf_t real_IO_vfscanf = NULL;
68 +static vfprintf_t real_vfprintf = NULL;
69 +static vsnprintf_t real_vsnprintf = NULL;
70 +static vsprintf_t real_vsprintf = NULL;
71 +static gets_t real_gets = NULL;
72 +static getwd_t real_getwd = NULL;
73 +static realpath_t real_realpath = NULL;
74 +static stpcpy_t real_stpcpy = NULL;
75 +static strcat_t real_strcat = NULL;
76 +static strcpy_t real_strcpy = NULL;
77 +static strncat_t real_strncat = NULL;
78 +static strncpy_t real_strncpy = NULL;
79 +static wcscpy_t real_wcscpy = NULL;
80 +static wcpcpy_t real_wcpcpy = NULL;
81 +#ifndef MISSING_WCSNLEN
82 +static wcscat_t real_wcscat = NULL;
85 * -------------- system library implementations -------------------
86 * Here is the story: if a C source file includes <string.h> and is
89 char *strcpy(char *dest, const char *src)
91 - static strcpy_t real_strcpy = NULL;
97 char *strncpy(char *dest, const char *src, size_t n)
99 - static strncpy_t real_strncpy = NULL;
100 size_t max_size, len;
105 char *stpcpy(char *dest, const char *src)
107 - static stpcpy_t real_stpcpy = NULL;
108 size_t max_size, len;
112 #ifndef MISSING_WCSNLEN
113 wchar_t *wcscpy(wchar_t *dest, const wchar_t *src)
115 - static wcscpy_t real_wcscpy = NULL;
116 size_t max_bytes, max_wchars, len;
121 wchar_t *wcpcpy(wchar_t *dest, const wchar_t *src)
123 - static wcpcpy_t real_wcpcpy = NULL;
124 size_t max_bytes, max_wchars, len;
129 char *strcat(char *dest, const char *src)
131 - static strcat_t real_strcat = NULL;
133 uint dest_len, src_len;
137 char *strncat(char *dest, const char *src, size_t n)
139 - static strncat_t real_strncat = NULL;
141 uint dest_len, src_len;
144 #ifndef MISSING_WCSNLEN
145 wchar_t *wcscat(wchar_t *dest, const wchar_t *src)
147 - static wcscat_t real_wcscat = NULL;
149 uint dest_len, src_len;
153 int vfprintf(FILE *fp, const char *format, va_list ap)
155 - static vfprintf_t real_vfprintf = NULL;
158 int c = -1; /* Next var arg to be used */
159 @@ -1026,7 +1032,6 @@
161 int _IO_vfprintf(FILE *fp, const char *format, va_list ap)
163 - static vfprintf_t real_vfprintf = NULL;
166 int c = -1; /* Next var arg to be used */
167 @@ -1189,8 +1194,6 @@
169 int sprintf(char *str, const char *format, ...)
171 - static vsprintf_t real_vsprintf = NULL;
172 - static vsnprintf_t real_vsnprintf = NULL;
176 @@ -1239,7 +1242,6 @@
178 int snprintf(char *str, size_t size, const char *format, ...)
180 - static vsnprintf_t real_vsnprintf = NULL;
184 @@ -1286,8 +1288,6 @@
186 int vsprintf(char *str, const char *format, va_list ap)
188 - static vsprintf_t real_vsprintf = NULL;
189 - static vsnprintf_t real_vsnprintf = NULL;
193 @@ -1325,7 +1325,6 @@
195 int vsnprintf(char *str, size_t size, const char *format, va_list ap)
197 - static vsnprintf_t real_vsnprintf = NULL;
201 @@ -1361,7 +1360,6 @@
203 char *getwd(char *buf)
205 - static getwd_t real_getwd = NULL;
209 @@ -1386,7 +1384,6 @@
213 - static gets_t real_gets = NULL;
214 size_t max_size, len;
217 @@ -1412,7 +1409,6 @@
219 char *realpath(char *path, char resolved_path[])
221 - static realpath_t real_realpath = NULL;
222 size_t max_size, len;
224 char buf[MAXPATHLEN + 1];
225 @@ -1445,7 +1441,6 @@
227 int _IO_vfscanf (_IO_FILE *s, const char *format, _IO_va_list argptr, int *errp)
229 - static _IO_vfscanf_t real_IO_vfscanf = NULL;
231 caddr_t ra_array[MAXLEVELS], fp_array[MAXLEVELS];
233 @@ -1529,6 +1524,25 @@
238 + real_memcpy = (memcpy_t) getLibraryFunction("memcpy");
239 + real_IO_vfscanf = (_IO_vfscanf_t) getLibraryFunction("_IO_vfscanf");
240 + real_vfprintf = (vfprintf_t) getLibraryFunction("vfprintf");
241 + real_vsnprintf = (vsnprintf_t) getLibraryFunction("vsnprintf");
242 + real_vsprintf = (vsprintf_t) getLibraryFunction("vsprintf");
243 + real_gets = (gets_t) getLibraryFunction("gets");
244 + real_getwd = (getwd_t) getLibraryFunction("getwd");
245 + real_realpath = (realpath_t) getLibraryFunction("realpath");
246 + real_stpcpy = (stpcpy_t) getLibraryFunction("stpcpy");
247 + real_strcat = (strcat_t) getLibraryFunction("strcat");
248 + real_strcpy = (strcpy_t) getLibraryFunction("strcpy");
249 + real_strncat = (strncat_t) getLibraryFunction("strncat");
250 + real_strncpy = (strncpy_t) getLibraryFunction("strncpy");
251 + real_wcscpy = (wcscpy_t) getLibraryFunction("wcscpy");
252 + real_wcpcpy = (wcpcpy_t) getLibraryFunction("wcpcpy");
253 +#ifndef MISSING_WCSNLEN
254 + real_wcscat = (wcscat_t) getLibraryFunction("wcscat");