~ubuntu-branches/ubuntu/precise/graphviz/precise-security

« back to all changes in this revision

Viewing changes to libltdl/loaders/loadlibrary.c

  • Committer: Bazaar Package Importer
  • Author(s): David Claughton
  • Date: 2010-03-24 22:45:18 UTC
  • mfrom: (1.2.7 upstream) (6.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100324224518-do441tthbqjaqjzd
Tags: 2.26.3-4
Add patch to fix segfault in circo. Backported from upstream snapshot
release.  Thanks to Francis Russell for his work on this.
(Closes: #575255)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* loader-loadlibrary.c --  dynamic linking for Win32
 
2
 
 
3
   Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
 
4
                 2007, 2008 Free Software Foundation, Inc.
 
5
   Written by Thomas Tanner, 1998
 
6
 
 
7
   NOTE: The canonical source of this file is maintained with the
 
8
   GNU Libtool package.  Report bugs to bug-libtool@gnu.org.
 
9
 
 
10
GNU Libltdl is free software; you can redistribute it and/or
 
11
modify it under the terms of the GNU Lesser General Public
 
12
License as published by the Free Software Foundation; either
 
13
version 2 of the License, or (at your option) any later version.
 
14
 
 
15
As a special exception to the GNU Lesser General Public License,
 
16
if you distribute this file as part of a program or library that
 
17
is built using GNU Libtool, you may include this file under the
 
18
same distribution terms that you use for the rest of that program.
 
19
 
 
20
GNU Libltdl is distributed in the hope that it will be useful,
 
21
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
22
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
23
GNU Lesser General Public License for more details.
 
24
 
 
25
You should have received a copy of the GNU Lesser General Public
 
26
License along with GNU Libltdl; see the file COPYING.LIB.  If not, a
 
27
copy can be downloaded from  http://www.gnu.org/licenses/lgpl.html,
 
28
or obtained by writing to the Free Software Foundation, Inc.,
 
29
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
30
*/
 
31
 
 
32
#include "lt__private.h"
 
33
#include "lt_dlloader.h"
 
34
 
 
35
#if defined(__CYGWIN__)
 
36
# include <sys/cygwin.h>
 
37
#endif
 
38
 
 
39
/* Use the preprocessor to rename non-static symbols to avoid namespace
 
40
   collisions when the loader code is statically linked into libltdl.
 
41
   Use the "<module_name>_LTX_" prefix so that the symbol addresses can
 
42
   be fetched from the preloaded symbol list by lt_dlsym():  */
 
43
#define get_vtable      loadlibrary_LTX_get_vtable
 
44
 
 
45
LT_BEGIN_C_DECLS
 
46
LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data);
 
47
LT_END_C_DECLS
 
48
 
 
49
 
 
50
/* Boilerplate code to set up the vtable for hooking this loader into
 
51
   libltdl's loader list:  */
 
52
static int       vl_exit  (lt_user_data loader_data);
 
53
static lt_module vm_open  (lt_user_data loader_data, const char *filename,
 
54
                           lt_dladvise advise);
 
55
static int       vm_close (lt_user_data loader_data, lt_module module);
 
56
static void *    vm_sym   (lt_user_data loader_data, lt_module module,
 
57
                          const char *symbolname);
 
58
 
 
59
static lt_dlinterface_id iface_id = 0;
 
60
static lt_dlvtable *vtable = 0;
 
61
 
 
62
/* Return the vtable for this loader, only the name and sym_prefix
 
63
   attributes (plus the virtual function implementations, obviously)
 
64
   change between loaders.  */
 
65
lt_dlvtable *
 
66
get_vtable (lt_user_data loader_data)
 
67
{
 
68
  if (!vtable)
 
69
    {
 
70
      vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
 
71
      iface_id = lt_dlinterface_register ("ltdl loadlibrary", NULL);
 
72
    }
 
73
 
 
74
  if (vtable && !vtable->name)
 
75
    {
 
76
      vtable->name              = "lt_loadlibrary";
 
77
      vtable->module_open       = vm_open;
 
78
      vtable->module_close      = vm_close;
 
79
      vtable->find_sym          = vm_sym;
 
80
      vtable->dlloader_exit     = vl_exit;
 
81
      vtable->dlloader_data     = loader_data;
 
82
      vtable->priority          = LT_DLLOADER_APPEND;
 
83
    }
 
84
 
 
85
  if (vtable && (vtable->dlloader_data != loader_data))
 
86
    {
 
87
      LT__SETERROR (INIT_LOADER);
 
88
      return 0;
 
89
    }
 
90
 
 
91
  return vtable;
 
92
}
 
93
 
 
94
 
 
95
 
 
96
/* --- IMPLEMENTATION --- */
 
97
 
 
98
 
 
99
#include <windows.h>
 
100
 
 
101
/* A function called through the vtable when this loader is no
 
102
   longer needed by the application.  */
 
103
static int
 
104
vl_exit (lt_user_data LT__UNUSED loader_data)
 
105
{
 
106
  vtable = NULL;
 
107
  return 0;
 
108
}
 
109
 
 
110
/* A function called through the vtable to open a module with this
 
111
   loader.  Returns an opaque representation of the newly opened
 
112
   module for processing with this loader's other vtable functions.  */
 
113
static lt_module
 
114
vm_open (lt_user_data LT__UNUSED loader_data, const char *filename,
 
115
         lt_dladvise LT__UNUSED advise)
 
116
{
 
117
  lt_module     module     = 0;
 
118
  char          *ext;
 
119
  char          wpath[MAX_PATH];
 
120
  size_t        len;
 
121
 
 
122
  if (!filename)
 
123
    {
 
124
      /* Get the name of main module */
 
125
      *wpath = 0;
 
126
      GetModuleFileName (NULL, wpath, sizeof (wpath));
 
127
      filename = wpath;
 
128
    }
 
129
  else
 
130
    {
 
131
      len = LT_STRLEN (filename);
 
132
 
 
133
      if (len >= MAX_PATH)
 
134
        {
 
135
          LT__SETERROR (CANNOT_OPEN);
 
136
          return 0;
 
137
        }
 
138
 
 
139
#if HAVE_DECL_CYGWIN_CONV_PATH
 
140
      if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, filename, wpath, MAX_PATH))
 
141
        {
 
142
          LT__SETERROR (CANNOT_OPEN);
 
143
          return 0;
 
144
        }
 
145
      len = 0;
 
146
#elif defined(__CYGWIN__)
 
147
      cygwin_conv_to_full_win32_path (filename, wpath);
 
148
      len = 0;
 
149
#else
 
150
      strcpy(wpath, filename);
 
151
#endif
 
152
 
 
153
      ext = strrchr (wpath, '.');
 
154
      if (!ext)
 
155
        {
 
156
          /* Append a `.' to stop Windows from adding an
 
157
             implicit `.dll' extension. */
 
158
          if (!len)
 
159
            len = LT_STRLEN (wpath);
 
160
 
 
161
          if (len + 1 >= MAX_PATH)
 
162
            {
 
163
              LT__SETERROR (CANNOT_OPEN);
 
164
              return 0;
 
165
            }
 
166
 
 
167
          wpath[len] = '.';
 
168
          wpath[len+1] = '\0';
 
169
        }
 
170
    }
 
171
 
 
172
  {
 
173
    /* Silence dialog from LoadLibrary on some failures.
 
174
       No way to get the error mode, but to set it,
 
175
       so set it twice to preserve any previous flags. */
 
176
    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
 
177
    SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
 
178
 
 
179
    module = LoadLibrary (wpath);
 
180
 
 
181
    /* Restore the error mode. */
 
182
    SetErrorMode(errormode);
 
183
  }
 
184
 
 
185
  /* libltdl expects this function to fail if it is unable
 
186
     to physically load the library.  Sadly, LoadLibrary
 
187
     will search the loaded libraries for a match and return
 
188
     one of them if the path search load fails.
 
189
 
 
190
     We check whether LoadLibrary is returning a handle to
 
191
     an already loaded module, and simulate failure if we
 
192
     find one. */
 
193
  {
 
194
    lt_dlhandle cur = 0;
 
195
 
 
196
    while ((cur = lt_dlhandle_iterate (iface_id, cur)))
 
197
      {
 
198
        if (!cur->module)
 
199
          {
 
200
            cur = 0;
 
201
            break;
 
202
          }
 
203
 
 
204
        if (cur->module == module)
 
205
          {
 
206
            break;
 
207
          }
 
208
      }
 
209
 
 
210
    if (cur || !module)
 
211
      {
 
212
        LT__SETERROR (CANNOT_OPEN);
 
213
        module = 0;
 
214
      }
 
215
  }
 
216
 
 
217
  return module;
 
218
}
 
219
 
 
220
 
 
221
/* A function called through the vtable when a particular module
 
222
   should be unloaded.  */
 
223
static int
 
224
vm_close (lt_user_data LT__UNUSED loader_data, lt_module module)
 
225
{
 
226
  int errors = 0;
 
227
 
 
228
  if (FreeLibrary((HMODULE) module) == 0)
 
229
    {
 
230
      LT__SETERROR (CANNOT_CLOSE);
 
231
      ++errors;
 
232
    }
 
233
 
 
234
  return errors;
 
235
}
 
236
 
 
237
 
 
238
/* A function called through the vtable to get the address of
 
239
   a symbol loaded from a particular module.  */
 
240
static void *
 
241
vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name)
 
242
{
 
243
  void *address = (void *) GetProcAddress ((HMODULE) module, name);
 
244
 
 
245
  if (!address)
 
246
    {
 
247
      LT__SETERROR (SYMBOL_NOT_FOUND);
 
248
    }
 
249
 
 
250
  return address;
 
251
}