VirtualBox

source: vbox/trunk/src/libs/openssl-3.0.3/crypto/dso/dso_lib.c@ 96662

Last change on this file since 96662 was 94082, checked in by vboxsync, 3 years ago

libs/openssl-3.0.1: started applying and adjusting our OpenSSL changes to 3.0.1. bugref:10128

File size: 8.7 KB
Line 
1/*
2 * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "dso_local.h"
11#include "internal/refcount.h"
12
13static DSO *DSO_new_method(DSO_METHOD *meth)
14{
15 DSO *ret;
16
17 ret = OPENSSL_zalloc(sizeof(*ret));
18 if (ret == NULL) {
19 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
20 return NULL;
21 }
22 ret->meth_data = sk_void_new_null();
23 if (ret->meth_data == NULL) {
24 /* sk_new doesn't generate any errors so we do */
25 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
26 OPENSSL_free(ret);
27 return NULL;
28 }
29 ret->meth = DSO_METHOD_openssl();
30 ret->references = 1;
31 ret->lock = CRYPTO_THREAD_lock_new();
32 if (ret->lock == NULL) {
33 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
34 sk_void_free(ret->meth_data);
35 OPENSSL_free(ret);
36 return NULL;
37 }
38
39 if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
40 DSO_free(ret);
41 ret = NULL;
42 }
43
44 return ret;
45}
46
47DSO *DSO_new(void)
48{
49 return DSO_new_method(NULL);
50}
51
52int DSO_free(DSO *dso)
53{
54 int i;
55
56 if (dso == NULL)
57 return 1;
58
59 if (CRYPTO_DOWN_REF(&dso->references, &i, dso->lock) <= 0)
60 return 0;
61
62 REF_PRINT_COUNT("DSO", dso);
63 if (i > 0)
64 return 1;
65 REF_ASSERT_ISNT(i < 0);
66
67 if ((dso->flags & DSO_FLAG_NO_UNLOAD_ON_FREE) == 0) {
68 if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
69 ERR_raise(ERR_LIB_DSO, DSO_R_UNLOAD_FAILED);
70 return 0;
71 }
72 }
73
74 if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
75 ERR_raise(ERR_LIB_DSO, DSO_R_FINISH_FAILED);
76 return 0;
77 }
78
79 sk_void_free(dso->meth_data);
80 OPENSSL_free(dso->filename);
81 OPENSSL_free(dso->loaded_filename);
82 CRYPTO_THREAD_lock_free(dso->lock);
83 OPENSSL_free(dso);
84 return 1;
85}
86
87int DSO_flags(DSO *dso)
88{
89 return ((dso == NULL) ? 0 : dso->flags);
90}
91
92int DSO_up_ref(DSO *dso)
93{
94 int i;
95
96 if (dso == NULL) {
97 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
98 return 0;
99 }
100
101 if (CRYPTO_UP_REF(&dso->references, &i, dso->lock) <= 0)
102 return 0;
103
104 REF_PRINT_COUNT("DSO", dso);
105 REF_ASSERT_ISNT(i < 2);
106 return ((i > 1) ? 1 : 0);
107}
108
109DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
110{
111 DSO *ret;
112 int allocated = 0;
113
114 if (dso == NULL) {
115 ret = DSO_new_method(meth);
116 if (ret == NULL) {
117 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
118 goto err;
119 }
120 allocated = 1;
121 /* Pass the provided flags to the new DSO object */
122 if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
123 ERR_raise(ERR_LIB_DSO, DSO_R_CTRL_FAILED);
124 goto err;
125 }
126 } else
127 ret = dso;
128 /* Don't load if we're currently already loaded */
129 if (ret->filename != NULL) {
130 ERR_raise(ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED);
131 goto err;
132 }
133 /*
134 * filename can only be NULL if we were passed a dso that already has one
135 * set.
136 */
137 if (filename != NULL)
138 if (!DSO_set_filename(ret, filename)) {
139 ERR_raise(ERR_LIB_DSO, DSO_R_SET_FILENAME_FAILED);
140 goto err;
141 }
142 filename = ret->filename;
143 if (filename == NULL) {
144 ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME);
145 goto err;
146 }
147 if (ret->meth->dso_load == NULL) {
148 ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
149 goto err;
150 }
151 if (!ret->meth->dso_load(ret)) {
152 ERR_raise(ERR_LIB_DSO, DSO_R_LOAD_FAILED);
153 goto err;
154 }
155 /* Load succeeded */
156 return ret;
157 err:
158 if (allocated)
159 DSO_free(ret);
160 return NULL;
161}
162
163DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
164{
165 DSO_FUNC_TYPE ret = NULL;
166
167 if ((dso == NULL) || (symname == NULL)) {
168 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
169 return NULL;
170 }
171 if (dso->meth->dso_bind_func == NULL) {
172 ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
173 return NULL;
174 }
175 if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
176 ERR_raise(ERR_LIB_DSO, DSO_R_SYM_FAILURE);
177 return NULL;
178 }
179 /* Success */
180 return ret;
181}
182
183/*
184 * I don't really like these *_ctrl functions very much to be perfectly
185 * honest. For one thing, I think I have to return a negative value for any
186 * error because possible DSO_ctrl() commands may return values such as
187 * "size"s that can legitimately be zero (making the standard
188 * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd
189 * times. I'd prefer "output" values to be passed by reference and the return
190 * value as success/failure like usual ... but we conform when we must... :-)
191 */
192long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
193{
194 if (dso == NULL) {
195 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
196 return -1;
197 }
198 /*
199 * We should intercept certain generic commands and only pass control to
200 * the method-specific ctrl() function if it's something we don't handle.
201 */
202 switch (cmd) {
203 case DSO_CTRL_GET_FLAGS:
204 return dso->flags;
205 case DSO_CTRL_SET_FLAGS:
206 dso->flags = (int)larg;
207 return 0;
208 case DSO_CTRL_OR_FLAGS:
209 dso->flags |= (int)larg;
210 return 0;
211 default:
212 break;
213 }
214 if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
215 ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
216 return -1;
217 }
218 return dso->meth->dso_ctrl(dso, cmd, larg, parg);
219}
220
221const char *DSO_get_filename(DSO *dso)
222{
223 if (dso == NULL) {
224 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
225 return NULL;
226 }
227 return dso->filename;
228}
229
230int DSO_set_filename(DSO *dso, const char *filename)
231{
232 char *copied;
233
234 if ((dso == NULL) || (filename == NULL)) {
235 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
236 return 0;
237 }
238 if (dso->loaded_filename) {
239 ERR_raise(ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED);
240 return 0;
241 }
242 /* We'll duplicate filename */
243 copied = OPENSSL_strdup(filename);
244 if (copied == NULL) {
245 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
246 return 0;
247 }
248 OPENSSL_free(dso->filename);
249 dso->filename = copied;
250 return 1;
251}
252
253char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
254{
255 char *result = NULL;
256
257 if (dso == NULL || filespec1 == NULL) {
258 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
259 return NULL;
260 }
261 if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
262 if (dso->merger != NULL)
263 result = dso->merger(dso, filespec1, filespec2);
264 else if (dso->meth->dso_merger != NULL)
265 result = dso->meth->dso_merger(dso, filespec1, filespec2);
266 }
267 return result;
268}
269
270char *DSO_convert_filename(DSO *dso, const char *filename)
271{
272 char *result = NULL;
273
274 if (dso == NULL) {
275 ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
276 return NULL;
277 }
278 if (filename == NULL)
279 filename = dso->filename;
280 if (filename == NULL) {
281 ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME);
282 return NULL;
283 }
284 if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
285 if (dso->name_converter != NULL)
286 result = dso->name_converter(dso, filename);
287 else if (dso->meth->dso_name_converter != NULL)
288 result = dso->meth->dso_name_converter(dso, filename);
289 }
290 if (result == NULL) {
291 result = OPENSSL_strdup(filename);
292 if (result == NULL) {
293 ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
294 return NULL;
295 }
296 }
297 return result;
298}
299
300int DSO_pathbyaddr(void *addr, char *path, int sz)
301{
302 DSO_METHOD *meth = DSO_METHOD_openssl();
303
304 if (meth->pathbyaddr == NULL) {
305 ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
306 return -1;
307 }
308 return (*meth->pathbyaddr) (addr, path, sz);
309}
310
311DSO *DSO_dsobyaddr(void *addr, int flags)
312{
313 DSO *ret = NULL;
314 char *filename = NULL;
315 int len = DSO_pathbyaddr(addr, NULL, 0);
316
317 if (len < 0)
318 return NULL;
319
320 filename = OPENSSL_malloc(len);
321 if (filename != NULL
322 && DSO_pathbyaddr(addr, filename, len) == len)
323 ret = DSO_load(NULL, filename, NULL, flags);
324
325 OPENSSL_free(filename);
326 return ret;
327}
328
329void *DSO_global_lookup(const char *name)
330{
331 DSO_METHOD *meth = DSO_METHOD_openssl();
332
333 if (meth->globallookup == NULL) {
334 ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
335 return NULL;
336 }
337 return (*meth->globallookup) (name);
338}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette