Merge lp:~racb/ubuntu/precise/apache2/988819 into lp:ubuntu/precise/apache2
- Precise (12.04)
- 988819
- Merge into precise
Proposed by
Robie Basak
on 2012-06-08
| Status: | Merged |
|---|---|
| Merge reported by: | Martin Pitt |
| Merged at revision: | not available |
| Proposed branch: | lp:~racb/ubuntu/precise/apache2/988819 |
| Merge into: | lp:ubuntu/precise/apache2 |
| Diff against target: |
773 lines (+641/-35) 6 files modified
.pc/083_dlopen_search_path/modules/mappers/mod_so.c (+434/-0) .pc/applied-patches (+1/-0) debian/changelog (+9/-0) debian/patches/083_dlopen_search_path (+152/-0) debian/patches/series (+1/-0) modules/mappers/mod_so.c (+44/-35) |
| To merge this branch: | bzr merge lp:~racb/ubuntu/precise/apache2/988819 |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| James Page | Approve on 2012-06-08 | ||
| Ubuntu branches | 2012-06-08 | Pending | |
|
Review via email:
|
|||
Commit Message
Description of the Change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
| 1 | === added directory '.pc/083_dlopen_search_path' |
| 2 | === added directory '.pc/083_dlopen_search_path/modules' |
| 3 | === added directory '.pc/083_dlopen_search_path/modules/mappers' |
| 4 | === added file '.pc/083_dlopen_search_path/modules/mappers/mod_so.c' |
| 5 | --- .pc/083_dlopen_search_path/modules/mappers/mod_so.c 1970-01-01 00:00:00 +0000 |
| 6 | +++ .pc/083_dlopen_search_path/modules/mappers/mod_so.c 2012-06-08 15:02:19 +0000 |
| 7 | @@ -0,0 +1,434 @@ |
| 8 | +/* Licensed to the Apache Software Foundation (ASF) under one or more |
| 9 | + * contributor license agreements. See the NOTICE file distributed with |
| 10 | + * this work for additional information regarding copyright ownership. |
| 11 | + * The ASF licenses this file to You under the Apache License, Version 2.0 |
| 12 | + * (the "License"); you may not use this file except in compliance with |
| 13 | + * the License. You may obtain a copy of the License at |
| 14 | + * |
| 15 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 16 | + * |
| 17 | + * Unless required by applicable law or agreed to in writing, software |
| 18 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 19 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 20 | + * See the License for the specific language governing permissions and |
| 21 | + * limitations under the License. |
| 22 | + */ |
| 23 | + |
| 24 | +/* |
| 25 | + * This module is used to load Apache modules at runtime. This means that the |
| 26 | + * server functionality can be extended without recompiling and even without |
| 27 | + * taking the server down at all. Only a HUP or AP_SIG_GRACEFUL signal |
| 28 | + * needs to be sent to the server to reload the dynamically loaded modules. |
| 29 | + * |
| 30 | + * To use, you'll first need to build your module as a shared library, then |
| 31 | + * update your configuration (httpd.conf) to get the Apache core to load the |
| 32 | + * module at start-up. |
| 33 | + * |
| 34 | + * The easiest way to build a module as a shared library is to use the |
| 35 | + * `SharedModule' command in the Configuration file, instead of `AddModule'. |
| 36 | + * You should also change the file extension from `.o' to `.so'. So, for |
| 37 | + * example, to build the status module as a shared library edit Configuration |
| 38 | + * and change |
| 39 | + * AddModule modules/standard/mod_status.o |
| 40 | + * to |
| 41 | + * SharedModule modules/standard/mod_status.so |
| 42 | + * |
| 43 | + * Run Configure and make. Now Apache's httpd binary will _not_ include |
| 44 | + * mod_status. Instead a shared object called mod_status.so will be build, in |
| 45 | + * the modules/standard directory. You can build most of the modules as shared |
| 46 | + * libraries like this. |
| 47 | + * |
| 48 | + * To use the shared module, move the .so file(s) into an appropriate |
| 49 | + * directory. You might like to create a directory called "modules" under you |
| 50 | + * server root for this (e.g. /usr/local/httpd/modules). |
| 51 | + * |
| 52 | + * Then edit your conf/httpd.conf file, and add LoadModule lines. For |
| 53 | + * example |
| 54 | + * LoadModule status_module modules/mod_status.so |
| 55 | + * |
| 56 | + * The first argument is the module's structure name (look at the end of the |
| 57 | + * module source to find this). The second option is the path to the module |
| 58 | + * file, relative to the server root. Put these directives right at the top |
| 59 | + * of your httpd.conf file. |
| 60 | + * |
| 61 | + * Now you can start Apache. A message will be logged at "debug" level to your |
| 62 | + * error_log to confirm that the module(s) are loaded (use "LogLevel debug" |
| 63 | + * directive to get these log messages). |
| 64 | + * |
| 65 | + * If you edit the LoadModule directives while the server is live you can get |
| 66 | + * Apache to re-load the modules by sending it a HUP or AP_SIG_GRACEFUL |
| 67 | + * signal as normal. You can use this to dynamically change the capability |
| 68 | + * of your server without bringing it down. |
| 69 | + * |
| 70 | + * Because currently there is only limited builtin support in the Configure |
| 71 | + * script for creating the shared library files (`.so'), please consult your |
| 72 | + * vendors cc(1), ld(1) and dlopen(3) manpages to find out the appropriate |
| 73 | + * compiler and linker flags and insert them manually into the Configuration |
| 74 | + * file under CFLAGS_SHLIB, LDFLAGS_SHLIB and LDFLAGS_SHLIB_EXPORT. |
| 75 | + * |
| 76 | + * If you still have problems figuring out the flags both try the paper |
| 77 | + * http://developer.netscape.com/library/documentation/enterprise |
| 78 | + * /unix/svrplug.htm#1013807 |
| 79 | + * or install a Perl 5 interpreter on your platform and then run the command |
| 80 | + * |
| 81 | + * $ perl -V:usedl -V:ccdlflags -V:cccdlflags -V:lddlflags |
| 82 | + * |
| 83 | + * This gives you what type of dynamic loading Perl 5 uses on your platform |
| 84 | + * and which compiler and linker flags Perl 5 uses to create the shared object |
| 85 | + * files. |
| 86 | + * |
| 87 | + * Another location where you can find useful hints is the `ltconfig' script |
| 88 | + * of the GNU libtool 1.2 package. Search for your platform name inside the |
| 89 | + * various "case" constructs. |
| 90 | + * |
| 91 | + */ |
| 92 | + |
| 93 | +#include "apr.h" |
| 94 | +#include "apr_dso.h" |
| 95 | +#include "apr_strings.h" |
| 96 | +#include "apr_errno.h" |
| 97 | + |
| 98 | +#define CORE_PRIVATE |
| 99 | +#include "ap_config.h" |
| 100 | +#include "httpd.h" |
| 101 | +#include "http_config.h" |
| 102 | +#include "http_log.h" |
| 103 | +#include "http_core.h" |
| 104 | + |
| 105 | +#include "mod_so.h" |
| 106 | + |
| 107 | +module AP_MODULE_DECLARE_DATA so_module; |
| 108 | + |
| 109 | + |
| 110 | +/* |
| 111 | + * Server configuration to keep track of actually |
| 112 | + * loaded modules and the corresponding module name. |
| 113 | + */ |
| 114 | + |
| 115 | +typedef struct so_server_conf { |
| 116 | + apr_array_header_t *loaded_modules; |
| 117 | +} so_server_conf; |
| 118 | + |
| 119 | +static void *so_sconf_create(apr_pool_t *p, server_rec *s) |
| 120 | +{ |
| 121 | + so_server_conf *soc; |
| 122 | + |
| 123 | + soc = (so_server_conf *)apr_pcalloc(p, sizeof(so_server_conf)); |
| 124 | + soc->loaded_modules = apr_array_make(p, DYNAMIC_MODULE_LIMIT, |
| 125 | + sizeof(ap_module_symbol_t)); |
| 126 | + |
| 127 | + return (void *)soc; |
| 128 | +} |
| 129 | + |
| 130 | +#ifndef NO_DLOPEN |
| 131 | + |
| 132 | +/* |
| 133 | + * This is the cleanup for a loaded shared object. It unloads the module. |
| 134 | + * This is called as a cleanup function from the core. |
| 135 | + */ |
| 136 | + |
| 137 | +static apr_status_t unload_module(void *data) |
| 138 | +{ |
| 139 | + ap_module_symbol_t *modi = (ap_module_symbol_t*)data; |
| 140 | + |
| 141 | + /* only unload if module information is still existing */ |
| 142 | + if (modi->modp == NULL) |
| 143 | + return APR_SUCCESS; |
| 144 | + |
| 145 | + /* remove the module pointer from the core structure */ |
| 146 | + ap_remove_loaded_module(modi->modp); |
| 147 | + |
| 148 | + /* destroy the module information */ |
| 149 | + modi->modp = NULL; |
| 150 | + modi->name = NULL; |
| 151 | + return APR_SUCCESS; |
| 152 | +} |
| 153 | + |
| 154 | +/* |
| 155 | + * This is called for the directive LoadModule and actually loads |
| 156 | + * a shared object file into the address space of the server process. |
| 157 | + */ |
| 158 | + |
| 159 | +static const char *load_module(cmd_parms *cmd, void *dummy, |
| 160 | + const char *modname, const char *filename) |
| 161 | +{ |
| 162 | + apr_dso_handle_t *modhandle; |
| 163 | + apr_dso_handle_sym_t modsym; |
| 164 | + module *modp; |
| 165 | + const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); |
| 166 | + so_server_conf *sconf; |
| 167 | + ap_module_symbol_t *modi; |
| 168 | + ap_module_symbol_t *modie; |
| 169 | + int i; |
| 170 | + const char *error; |
| 171 | + |
| 172 | + /* we need to setup this value for dummy to make sure that we don't try |
| 173 | + * to add a non-existant tree into the build when we return to |
| 174 | + * execute_now. |
| 175 | + */ |
| 176 | + *(ap_directive_t **)dummy = NULL; |
| 177 | + |
| 178 | + if (!szModuleFile) { |
| 179 | + return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", |
| 180 | + filename, NULL); |
| 181 | + } |
| 182 | + |
| 183 | + /* |
| 184 | + * check for already existing module |
| 185 | + * If it already exists, we have nothing to do |
| 186 | + * Check both dynamically-loaded modules and statically-linked modules. |
| 187 | + */ |
| 188 | + sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config, |
| 189 | + &so_module); |
| 190 | + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; |
| 191 | + for (i = 0; i < sconf->loaded_modules->nelts; i++) { |
| 192 | + modi = &modie[i]; |
| 193 | + if (modi->name != NULL && strcmp(modi->name, modname) == 0) { |
| 194 | + ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, |
| 195 | + cmd->pool, "module %s is already loaded, skipping", |
| 196 | + modname); |
| 197 | + return NULL; |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + for (i = 0; ap_preloaded_modules[i]; i++) { |
| 202 | + const char *preload_name; |
| 203 | + apr_size_t preload_len; |
| 204 | + apr_size_t thismod_len; |
| 205 | + |
| 206 | + modp = ap_preloaded_modules[i]; |
| 207 | + |
| 208 | + /* make sure we're comparing apples with apples |
| 209 | + * make sure name of preloaded module is mod_FOO.c |
| 210 | + * make sure name of structure being loaded is FOO_module |
| 211 | + */ |
| 212 | + |
| 213 | + if (memcmp(modp->name, "mod_", 4)) { |
| 214 | + continue; |
| 215 | + } |
| 216 | + |
| 217 | + preload_name = modp->name + strlen("mod_"); |
| 218 | + preload_len = strlen(preload_name) - 2; |
| 219 | + |
| 220 | + if (strlen(modname) <= strlen("_module")) { |
| 221 | + continue; |
| 222 | + } |
| 223 | + thismod_len = strlen(modname) - strlen("_module"); |
| 224 | + if (strcmp(modname + thismod_len, "_module")) { |
| 225 | + continue; |
| 226 | + } |
| 227 | + |
| 228 | + if (thismod_len != preload_len) { |
| 229 | + continue; |
| 230 | + } |
| 231 | + |
| 232 | + if (!memcmp(modname, preload_name, preload_len)) { |
| 233 | + return apr_pstrcat(cmd->pool, "module ", modname, |
| 234 | + " is built-in and can't be loaded", |
| 235 | + NULL); |
| 236 | + } |
| 237 | + } |
| 238 | + |
| 239 | + modi = apr_array_push(sconf->loaded_modules); |
| 240 | + modi->name = modname; |
| 241 | + |
| 242 | + /* |
| 243 | + * Load the file into the Apache address space |
| 244 | + */ |
| 245 | + if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { |
| 246 | + char my_error[256]; |
| 247 | + |
| 248 | + return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, |
| 249 | + " into server: ", |
| 250 | + apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 251 | + NULL); |
| 252 | + } |
| 253 | + ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, |
| 254 | + "loaded module %s", modname); |
| 255 | + |
| 256 | + /* |
| 257 | + * Retrieve the pointer to the module structure through the module name: |
| 258 | + * First with the hidden variant (prefix `AP_') and then with the plain |
| 259 | + * symbol name. |
| 260 | + */ |
| 261 | + if (apr_dso_sym(&modsym, modhandle, modname) != APR_SUCCESS) { |
| 262 | + char my_error[256]; |
| 263 | + |
| 264 | + return apr_pstrcat(cmd->pool, "Can't locate API module structure `", |
| 265 | + modname, "' in file ", szModuleFile, ": ", |
| 266 | + apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 267 | + NULL); |
| 268 | + } |
| 269 | + modp = (module*) modsym; |
| 270 | + modp->dynamic_load_handle = (apr_dso_handle_t *)modhandle; |
| 271 | + modi->modp = modp; |
| 272 | + |
| 273 | + /* |
| 274 | + * Make sure the found module structure is really a module structure |
| 275 | + * |
| 276 | + */ |
| 277 | + if (modp->magic != MODULE_MAGIC_COOKIE) { |
| 278 | + return apr_psprintf(cmd->pool, "API module structure '%s' in file %s " |
| 279 | + "is garbled - expected signature %08lx but saw " |
| 280 | + "%08lx - perhaps this is not an Apache module DSO, " |
| 281 | + "or was compiled for a different Apache version?", |
| 282 | + modname, szModuleFile, |
| 283 | + MODULE_MAGIC_COOKIE, modp->magic); |
| 284 | + } |
| 285 | + |
| 286 | + /* |
| 287 | + * Add this module to the Apache core structures |
| 288 | + */ |
| 289 | + error = ap_add_loaded_module(modp, cmd->pool); |
| 290 | + if (error) { |
| 291 | + return error; |
| 292 | + } |
| 293 | + |
| 294 | + /* |
| 295 | + * Register a cleanup in the config apr_pool_t (normally pconf). When |
| 296 | + * we do a restart (or shutdown) this cleanup will cause the |
| 297 | + * shared object to be unloaded. |
| 298 | + */ |
| 299 | + apr_pool_cleanup_register(cmd->pool, modi, unload_module, apr_pool_cleanup_null); |
| 300 | + |
| 301 | + /* |
| 302 | + * Finally we need to run the configuration process for the module |
| 303 | + */ |
| 304 | + ap_single_module_configure(cmd->pool, cmd->server, modp); |
| 305 | + |
| 306 | + return NULL; |
| 307 | +} |
| 308 | + |
| 309 | +/* |
| 310 | + * This implements the LoadFile directive and loads an arbitrary |
| 311 | + * shared object file into the adress space of the server process. |
| 312 | + */ |
| 313 | + |
| 314 | +static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) |
| 315 | +{ |
| 316 | + apr_dso_handle_t *handle; |
| 317 | + const char *file; |
| 318 | + |
| 319 | + file = ap_server_root_relative(cmd->pool, filename); |
| 320 | + |
| 321 | + if (!file) { |
| 322 | + return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", |
| 323 | + filename, NULL); |
| 324 | + } |
| 325 | + |
| 326 | + if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { |
| 327 | + char my_error[256]; |
| 328 | + |
| 329 | + return apr_pstrcat(cmd->pool, "Cannot load ", filename, |
| 330 | + " into server: ", |
| 331 | + apr_dso_error(handle, my_error, sizeof(my_error)), |
| 332 | + NULL); |
| 333 | + } |
| 334 | + |
| 335 | + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, |
| 336 | + "loaded file %s", filename); |
| 337 | + |
| 338 | + return NULL; |
| 339 | +} |
| 340 | + |
| 341 | +static module *ap_find_loaded_module_symbol(server_rec *s, const char *modname) |
| 342 | +{ |
| 343 | + so_server_conf *sconf; |
| 344 | + ap_module_symbol_t *modi; |
| 345 | + ap_module_symbol_t *modie; |
| 346 | + int i; |
| 347 | + |
| 348 | + sconf = (so_server_conf *)ap_get_module_config(s->module_config, |
| 349 | + &so_module); |
| 350 | + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; |
| 351 | + |
| 352 | + for (i = 0; i < sconf->loaded_modules->nelts; i++) { |
| 353 | + modi = &modie[i]; |
| 354 | + if (modi->name != NULL && strcmp(modi->name, modname) == 0) { |
| 355 | + return modi->modp; |
| 356 | + } |
| 357 | + } |
| 358 | + return NULL; |
| 359 | +} |
| 360 | + |
| 361 | +static void dump_loaded_modules(apr_pool_t *p, server_rec *s) |
| 362 | +{ |
| 363 | + ap_module_symbol_t *modie; |
| 364 | + ap_module_symbol_t *modi; |
| 365 | + so_server_conf *sconf; |
| 366 | + int i; |
| 367 | + apr_file_t *out = NULL; |
| 368 | + |
| 369 | + if (!ap_exists_config_define("DUMP_MODULES")) { |
| 370 | + return; |
| 371 | + } |
| 372 | + |
| 373 | + apr_file_open_stdout(&out, p); |
| 374 | + |
| 375 | + apr_file_printf(out, "Loaded Modules:\n"); |
| 376 | + |
| 377 | + sconf = (so_server_conf *)ap_get_module_config(s->module_config, |
| 378 | + &so_module); |
| 379 | + for (i = 0; ; i++) { |
| 380 | + modi = &ap_prelinked_module_symbols[i]; |
| 381 | + if (modi->name != NULL) { |
| 382 | + apr_file_printf(out, " %s (static)\n", modi->name); |
| 383 | + } |
| 384 | + else { |
| 385 | + break; |
| 386 | + } |
| 387 | + } |
| 388 | + |
| 389 | + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; |
| 390 | + for (i = 0; i < sconf->loaded_modules->nelts; i++) { |
| 391 | + modi = &modie[i]; |
| 392 | + if (modi->name != NULL) { |
| 393 | + apr_file_printf(out, " %s (shared)\n", modi->name); |
| 394 | + } |
| 395 | + } |
| 396 | +} |
| 397 | + |
| 398 | +#else /* not NO_DLOPEN */ |
| 399 | + |
| 400 | +static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) |
| 401 | +{ |
| 402 | + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, |
| 403 | + "WARNING: LoadFile not supported on this platform"); |
| 404 | + return NULL; |
| 405 | +} |
| 406 | + |
| 407 | +static const char *load_module(cmd_parms *cmd, void *dummy, |
| 408 | + const char *modname, const char *filename) |
| 409 | +{ |
| 410 | + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, |
| 411 | + "WARNING: LoadModule not supported on this platform"); |
| 412 | + return NULL; |
| 413 | +} |
| 414 | + |
| 415 | +#endif /* NO_DLOPEN */ |
| 416 | + |
| 417 | +static void register_hooks(apr_pool_t *p) |
| 418 | +{ |
| 419 | +#ifndef NO_DLOPEN |
| 420 | + APR_REGISTER_OPTIONAL_FN(ap_find_loaded_module_symbol); |
| 421 | + ap_hook_test_config(dump_loaded_modules, NULL, NULL, APR_HOOK_MIDDLE); |
| 422 | +#endif |
| 423 | +} |
| 424 | + |
| 425 | +static const command_rec so_cmds[] = { |
| 426 | + AP_INIT_TAKE2("LoadModule", load_module, NULL, RSRC_CONF | EXEC_ON_READ, |
| 427 | + "a module name and the name of a shared object file to load it from"), |
| 428 | + AP_INIT_ITERATE("LoadFile", load_file, NULL, RSRC_CONF | EXEC_ON_READ, |
| 429 | + "shared object file or library to load into the server at runtime"), |
| 430 | + { NULL } |
| 431 | +}; |
| 432 | + |
| 433 | +module AP_MODULE_DECLARE_DATA so_module = { |
| 434 | + STANDARD20_MODULE_STUFF, |
| 435 | + NULL, /* create per-dir config */ |
| 436 | + NULL, /* merge per-dir config */ |
| 437 | + so_sconf_create, /* server config */ |
| 438 | + NULL, /* merge server config */ |
| 439 | + so_cmds, /* command apr_table_t */ |
| 440 | + register_hooks /* register hooks */ |
| 441 | +}; |
| 442 | |
| 443 | === modified file '.pc/applied-patches' |
| 444 | --- .pc/applied-patches 2012-02-01 21:49:04 +0000 |
| 445 | +++ .pc/applied-patches 2012-06-08 15:02:19 +0000 |
| 446 | @@ -21,5 +21,6 @@ |
| 447 | 077_CacheIgnoreURLSessionIdentifiers |
| 448 | 079_polish_translation |
| 449 | 082_ab_num_requests |
| 450 | +083_dlopen_search_path |
| 451 | 099_config_guess_sub_update |
| 452 | 201_build_suexec-custom |
| 453 | |
| 454 | === modified file 'debian/changelog' |
| 455 | --- debian/changelog 2012-02-12 20:06:35 +0000 |
| 456 | +++ debian/changelog 2012-06-08 15:02:19 +0000 |
| 457 | @@ -1,3 +1,12 @@ |
| 458 | +apache2 (2.2.22-1ubuntu1.1) precise-proposed; urgency=low |
| 459 | + |
| 460 | + * debian/patches/083_dlopen_search_path: use dlopen() search path to |
| 461 | + enable modules that use multiarch, such as libapache2-modsecurity. |
| 462 | + These modules can now use no path and apache2 will be able to find |
| 463 | + them (LP: #988819). |
| 464 | + |
| 465 | + -- Robie Basak <robie.basak@ubuntu.com> Fri, 08 Jun 2012 15:45:02 +0100 |
| 466 | + |
| 467 | apache2 (2.2.22-1ubuntu1) precise; urgency=low |
| 468 | |
| 469 | * Merge from Debian testing. Remaining changes: |
| 470 | |
| 471 | === added file 'debian/patches/083_dlopen_search_path' |
| 472 | --- debian/patches/083_dlopen_search_path 1970-01-01 00:00:00 +0000 |
| 473 | +++ debian/patches/083_dlopen_search_path 2012-06-08 15:02:19 +0000 |
| 474 | @@ -0,0 +1,152 @@ |
| 475 | +Backport r1332378 from upstream trunk: |
| 476 | + |
| 477 | +If a filename without slashes is specified for LoadFile or |
| 478 | +LoadModule and the file cannot be found in the server root directory, |
| 479 | +try to use the standard dlopen() search path. |
| 480 | + |
| 481 | +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1332378 13f79535-47bb-0310-9956-ffa450edef68 |
| 482 | + |
| 483 | +Author: Stefan Fritsch |
| 484 | +Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1332378 |
| 485 | +Bug-Debian: http://bugs.debian.org/670247 |
| 486 | +Bug-Ubuntu: https://launchpad.net/bugs/988819 |
| 487 | +Last-Update: 2012-06-08 |
| 488 | + |
| 489 | +--- |
| 490 | + modules/mappers/mod_so.c | 77 ++++++++++++++++++++++++++-------------------- |
| 491 | + 1 file changed, 43 insertions(+), 34 deletions(-) |
| 492 | + |
| 493 | +diff --git a/modules/mappers/mod_so.c b/modules/mappers/mod_so.c |
| 494 | +index 2d4a54c..6a9fdae 100644 |
| 495 | +--- a/modules/mappers/mod_so.c |
| 496 | ++++ b/modules/mappers/mod_so.c |
| 497 | +@@ -144,6 +144,37 @@ static apr_status_t unload_module(void *data) |
| 498 | + return APR_SUCCESS; |
| 499 | + } |
| 500 | + |
| 501 | ++static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep, |
| 502 | ++ const char *filename, const char **used_filename) |
| 503 | ++{ |
| 504 | ++ int retry = 0; |
| 505 | ++ const char *fullname = ap_server_root_relative(cmd->temp_pool, filename); |
| 506 | ++ char my_error[256]; |
| 507 | ++ if (filename != NULL && ap_strchr_c(filename, '/') == NULL) { |
| 508 | ++ /* retry on error without path to use dlopen()'s search path */ |
| 509 | ++ retry = 1; |
| 510 | ++ } |
| 511 | ++ |
| 512 | ++ if (fullname == NULL && !retry) { |
| 513 | ++ return apr_psprintf(cmd->temp_pool, "Invalid %s path %s", |
| 514 | ++ cmd->cmd->name, filename); |
| 515 | ++ } |
| 516 | ++ *used_filename = fullname; |
| 517 | ++ if (apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) { |
| 518 | ++ return NULL; |
| 519 | ++ } |
| 520 | ++ if (retry) { |
| 521 | ++ *used_filename = filename; |
| 522 | ++ if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS) |
| 523 | ++ return NULL; |
| 524 | ++ } |
| 525 | ++ |
| 526 | ++ return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename, |
| 527 | ++ " into server: ", |
| 528 | ++ apr_dso_error(*modhandlep, my_error, sizeof(my_error)), |
| 529 | ++ NULL); |
| 530 | ++} |
| 531 | ++ |
| 532 | + /* |
| 533 | + * This is called for the directive LoadModule and actually loads |
| 534 | + * a shared object file into the address space of the server process. |
| 535 | +@@ -155,7 +186,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 536 | + apr_dso_handle_t *modhandle; |
| 537 | + apr_dso_handle_sym_t modsym; |
| 538 | + module *modp; |
| 539 | +- const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); |
| 540 | ++ const char *module_file; |
| 541 | + so_server_conf *sconf; |
| 542 | + ap_module_symbol_t *modi; |
| 543 | + ap_module_symbol_t *modie; |
| 544 | +@@ -168,11 +199,6 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 545 | + */ |
| 546 | + *(ap_directive_t **)dummy = NULL; |
| 547 | + |
| 548 | +- if (!szModuleFile) { |
| 549 | +- return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", |
| 550 | +- filename, NULL); |
| 551 | +- } |
| 552 | +- |
| 553 | + /* |
| 554 | + * check for already existing module |
| 555 | + * If it already exists, we have nothing to do |
| 556 | +@@ -235,16 +261,11 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 557 | + /* |
| 558 | + * Load the file into the Apache address space |
| 559 | + */ |
| 560 | +- if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { |
| 561 | +- char my_error[256]; |
| 562 | +- |
| 563 | +- return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, |
| 564 | +- " into server: ", |
| 565 | +- apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 566 | +- NULL); |
| 567 | +- } |
| 568 | ++ error = dso_load(cmd, &modhandle, filename, &module_file); |
| 569 | ++ if (error) |
| 570 | ++ return error; |
| 571 | + ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, |
| 572 | +- "loaded module %s", modname); |
| 573 | ++ "loaded module %s from %s", modname, module_file); |
| 574 | + |
| 575 | + /* |
| 576 | + * Retrieve the pointer to the module structure through the module name: |
| 577 | +@@ -255,7 +276,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 578 | + char my_error[256]; |
| 579 | + |
| 580 | + return apr_pstrcat(cmd->pool, "Can't locate API module structure `", |
| 581 | +- modname, "' in file ", szModuleFile, ": ", |
| 582 | ++ modname, "' in file ", module_file, ": ", |
| 583 | + apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 584 | + NULL); |
| 585 | + } |
| 586 | +@@ -272,7 +293,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 587 | + "is garbled - expected signature %08lx but saw " |
| 588 | + "%08lx - perhaps this is not an Apache module DSO, " |
| 589 | + "or was compiled for a different Apache version?", |
| 590 | +- modname, szModuleFile, |
| 591 | ++ modname, module_file, |
| 592 | + MODULE_MAGIC_COOKIE, modp->magic); |
| 593 | + } |
| 594 | + |
| 595 | +@@ -307,26 +328,14 @@ static const char *load_module(cmd_parms *cmd, void *dummy, |
| 596 | + static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) |
| 597 | + { |
| 598 | + apr_dso_handle_t *handle; |
| 599 | +- const char *file; |
| 600 | +- |
| 601 | +- file = ap_server_root_relative(cmd->pool, filename); |
| 602 | ++ const char *used_file, *error; |
| 603 | + |
| 604 | +- if (!file) { |
| 605 | +- return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", |
| 606 | +- filename, NULL); |
| 607 | +- } |
| 608 | +- |
| 609 | +- if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { |
| 610 | +- char my_error[256]; |
| 611 | +- |
| 612 | +- return apr_pstrcat(cmd->pool, "Cannot load ", filename, |
| 613 | +- " into server: ", |
| 614 | +- apr_dso_error(handle, my_error, sizeof(my_error)), |
| 615 | +- NULL); |
| 616 | +- } |
| 617 | ++ error = dso_load(cmd, &handle, filename, &used_file); |
| 618 | ++ if (error) |
| 619 | ++ return error; |
| 620 | + |
| 621 | + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, |
| 622 | +- "loaded file %s", filename); |
| 623 | ++ "loaded file %s", used_file); |
| 624 | + |
| 625 | + return NULL; |
| 626 | + } |
| 627 | |
| 628 | === modified file 'debian/patches/series' |
| 629 | --- debian/patches/series 2012-02-01 21:49:04 +0000 |
| 630 | +++ debian/patches/series 2012-06-08 15:02:19 +0000 |
| 631 | @@ -21,6 +21,7 @@ |
| 632 | 077_CacheIgnoreURLSessionIdentifiers |
| 633 | 079_polish_translation |
| 634 | 082_ab_num_requests |
| 635 | +083_dlopen_search_path |
| 636 | 099_config_guess_sub_update |
| 637 | 201_build_suexec-custom |
| 638 | # The patch below must not be applied by quilt at extraction time. It depends |
| 639 | |
| 640 | === modified file 'modules/mappers/mod_so.c' |
| 641 | --- modules/mappers/mod_so.c 2009-08-04 11:02:34 +0000 |
| 642 | +++ modules/mappers/mod_so.c 2012-06-08 15:02:19 +0000 |
| 643 | @@ -144,6 +144,37 @@ |
| 644 | return APR_SUCCESS; |
| 645 | } |
| 646 | |
| 647 | +static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep, |
| 648 | + const char *filename, const char **used_filename) |
| 649 | +{ |
| 650 | + int retry = 0; |
| 651 | + const char *fullname = ap_server_root_relative(cmd->temp_pool, filename); |
| 652 | + char my_error[256]; |
| 653 | + if (filename != NULL && ap_strchr_c(filename, '/') == NULL) { |
| 654 | + /* retry on error without path to use dlopen()'s search path */ |
| 655 | + retry = 1; |
| 656 | + } |
| 657 | + |
| 658 | + if (fullname == NULL && !retry) { |
| 659 | + return apr_psprintf(cmd->temp_pool, "Invalid %s path %s", |
| 660 | + cmd->cmd->name, filename); |
| 661 | + } |
| 662 | + *used_filename = fullname; |
| 663 | + if (apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) { |
| 664 | + return NULL; |
| 665 | + } |
| 666 | + if (retry) { |
| 667 | + *used_filename = filename; |
| 668 | + if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS) |
| 669 | + return NULL; |
| 670 | + } |
| 671 | + |
| 672 | + return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename, |
| 673 | + " into server: ", |
| 674 | + apr_dso_error(*modhandlep, my_error, sizeof(my_error)), |
| 675 | + NULL); |
| 676 | +} |
| 677 | + |
| 678 | /* |
| 679 | * This is called for the directive LoadModule and actually loads |
| 680 | * a shared object file into the address space of the server process. |
| 681 | @@ -155,7 +186,7 @@ |
| 682 | apr_dso_handle_t *modhandle; |
| 683 | apr_dso_handle_sym_t modsym; |
| 684 | module *modp; |
| 685 | - const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); |
| 686 | + const char *module_file; |
| 687 | so_server_conf *sconf; |
| 688 | ap_module_symbol_t *modi; |
| 689 | ap_module_symbol_t *modie; |
| 690 | @@ -168,11 +199,6 @@ |
| 691 | */ |
| 692 | *(ap_directive_t **)dummy = NULL; |
| 693 | |
| 694 | - if (!szModuleFile) { |
| 695 | - return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", |
| 696 | - filename, NULL); |
| 697 | - } |
| 698 | - |
| 699 | /* |
| 700 | * check for already existing module |
| 701 | * If it already exists, we have nothing to do |
| 702 | @@ -235,16 +261,11 @@ |
| 703 | /* |
| 704 | * Load the file into the Apache address space |
| 705 | */ |
| 706 | - if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { |
| 707 | - char my_error[256]; |
| 708 | - |
| 709 | - return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, |
| 710 | - " into server: ", |
| 711 | - apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 712 | - NULL); |
| 713 | - } |
| 714 | + error = dso_load(cmd, &modhandle, filename, &module_file); |
| 715 | + if (error) |
| 716 | + return error; |
| 717 | ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, |
| 718 | - "loaded module %s", modname); |
| 719 | + "loaded module %s from %s", modname, module_file); |
| 720 | |
| 721 | /* |
| 722 | * Retrieve the pointer to the module structure through the module name: |
| 723 | @@ -255,7 +276,7 @@ |
| 724 | char my_error[256]; |
| 725 | |
| 726 | return apr_pstrcat(cmd->pool, "Can't locate API module structure `", |
| 727 | - modname, "' in file ", szModuleFile, ": ", |
| 728 | + modname, "' in file ", module_file, ": ", |
| 729 | apr_dso_error(modhandle, my_error, sizeof(my_error)), |
| 730 | NULL); |
| 731 | } |
| 732 | @@ -272,7 +293,7 @@ |
| 733 | "is garbled - expected signature %08lx but saw " |
| 734 | "%08lx - perhaps this is not an Apache module DSO, " |
| 735 | "or was compiled for a different Apache version?", |
| 736 | - modname, szModuleFile, |
| 737 | + modname, module_file, |
| 738 | MODULE_MAGIC_COOKIE, modp->magic); |
| 739 | } |
| 740 | |
| 741 | @@ -307,26 +328,14 @@ |
| 742 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) |
| 743 | { |
| 744 | apr_dso_handle_t *handle; |
| 745 | - const char *file; |
| 746 | - |
| 747 | - file = ap_server_root_relative(cmd->pool, filename); |
| 748 | - |
| 749 | - if (!file) { |
| 750 | - return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", |
| 751 | - filename, NULL); |
| 752 | - } |
| 753 | - |
| 754 | - if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { |
| 755 | - char my_error[256]; |
| 756 | - |
| 757 | - return apr_pstrcat(cmd->pool, "Cannot load ", filename, |
| 758 | - " into server: ", |
| 759 | - apr_dso_error(handle, my_error, sizeof(my_error)), |
| 760 | - NULL); |
| 761 | - } |
| 762 | + const char *used_file, *error; |
| 763 | + |
| 764 | + error = dso_load(cmd, &handle, filename, &used_file); |
| 765 | + if (error) |
| 766 | + return error; |
| 767 | |
| 768 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, |
| 769 | - "loaded file %s", filename); |
| 770 | + "loaded file %s", used_file); |
| 771 | |
| 772 | return NULL; |
| 773 | } |


Uploaded to -proposed