Make LOAD of an already-loaded library into a no-op, instead of attempting

to unload and re-load the library.

The difficulty with unloading a library is that we haven't defined safe
protocols for doing so.  In particular, there's no safe mechanism for
getting out of a "hook" function pointer unless libraries are unloaded
in reverse order of loading.  And there's no mechanism at all for undefining
a custom GUC variable, so GUC would be left with a pointer to an old value
that might or might not still be valid, and very possibly wouldn't be in
the same place anymore.

While the unload and reload behavior had some usefulness in easing
development of new loadable libraries, it's of no use whatever to normal
users, so just disabling it isn't giving up that much.  Someday we might
care to expend the effort to develop safe unload protocols; but even if
we did, there'd be little certainty that every third-party loadable module
was following them, so some security restrictions would still be needed.

Back-patch to 8.2; before that, LOAD was superuser-only anyway.

Security: unprivileged users could crash backend.  CVE not assigned yet
This commit is contained in:
Tom Lane 2009-09-03 22:11:13 +00:00
parent 4fd4bf4bd8
commit 57710f39cc
4 changed files with 23 additions and 19 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.84 2008/12/31 02:25:03 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.84.2.1 2009/09/03 22:11:13 tgl Exp $
--> -->
<refentry id="SQL-CREATEFUNCTION"> <refentry id="SQL-CREATEFUNCTION">
@ -528,8 +528,7 @@ CREATE FUNCTION foo(int, int default 42) ...
When repeated <command>CREATE FUNCTION</command> calls refer to When repeated <command>CREATE FUNCTION</command> calls refer to
the same object file, the file is only loaded once per session. the same object file, the file is only loaded once per session.
To unload and To unload and
reload the file (perhaps during development), use the <xref reload the file (perhaps during development), start a new session.
linkend="sql-load" endterm="sql-load-title"> command.
</para> </para>
<para> <para>

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/load.sgml,v 1.25 2008/11/14 10:22:47 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/load.sgml,v 1.25.2.1 2009/09/03 22:11:13 tgl Exp $
--> -->
<refentry id="SQL-LOAD"> <refentry id="SQL-LOAD">
@ -11,7 +11,7 @@ $PostgreSQL: pgsql/doc/src/sgml/ref/load.sgml,v 1.25 2008/11/14 10:22:47 petere
<refnamediv> <refnamediv>
<refname>LOAD</refname> <refname>LOAD</refname>
<refpurpose>load or reload a shared library file</refpurpose> <refpurpose>load a shared library file</refpurpose>
</refnamediv> </refnamediv>
<indexterm zone="sql-load"> <indexterm zone="sql-load">
@ -29,13 +29,12 @@ LOAD '<replaceable class="PARAMETER">filename</replaceable>'
<para> <para>
This command loads a shared library file into the <productname>PostgreSQL</> This command loads a shared library file into the <productname>PostgreSQL</>
server's address space. If the file had been loaded previously, server's address space. If the file has been loaded already,
it is first unloaded. This command is primarily useful to unload the command does nothing. Shared library files that contain C functions
and reload a shared library file that has been changed since the are automatically loaded whenever one of their functions is called.
server first loaded it. To make use of the shared library, Therefore, an explicit <command>LOAD</> is usually only needed to
function(s) in it need to be declared using the <xref load a library that modifies the server's behavior through <quote>hooks</>
linkend="sql-createfunction" endterm="sql-createfunction-title"> rather than providing a set of functions.
command.
</para> </para>
<para> <para>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.138 2009/05/27 01:18:06 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.138.2.1 2009/09/03 22:11:13 tgl Exp $ -->
<sect1 id="xfunc"> <sect1 id="xfunc">
<title>User-Defined Functions</title> <title>User-Defined Functions</title>
@ -1481,9 +1481,7 @@ PG_MODULE_MAGIC;
file is retained in memory. Future calls in the same session to file is retained in memory. Future calls in the same session to
the function(s) in that file will only incur the small overhead of the function(s) in that file will only incur the small overhead of
a symbol table lookup. If you need to force a reload of an object a symbol table lookup. If you need to force a reload of an object
file, for example after recompiling it, use the <xref file, for example after recompiling it, begin a fresh session.
linkend="sql-load" endterm="sql-load-title"> command or begin a
fresh session.
</para> </para>
<indexterm zone="xfunc-c-dynload"> <indexterm zone="xfunc-c-dynload">
@ -1509,8 +1507,8 @@ PG_MODULE_MAGIC;
unloading the file. Likewise, the function receives no parameters and unloading the file. Likewise, the function receives no parameters and
should return void. Note that <function>_PG_fini</> will only be called should return void. Note that <function>_PG_fini</> will only be called
during an unload of the file, not during process termination. during an unload of the file, not during process termination.
(Presently, an unload only happens in the context of re-loading (Presently, unloads are disabled and will never occur, but this may
the file due to an explicit <command>LOAD</> command.) change in the future.)
</para> </para>
</sect2> </sect2>

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.99 2009/06/11 14:49:05 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.99.2.1 2009/09/03 22:11:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -385,10 +385,17 @@ incompatible_module_error(const char *libname,
* Unload the specified dynamic-link library file, if it is loaded. * Unload the specified dynamic-link library file, if it is loaded.
* *
* Note: libname is expected to be an exact name for the library file. * Note: libname is expected to be an exact name for the library file.
*
* XXX for the moment, this is disabled, resulting in LOAD of an already-loaded
* library always being a no-op. We might re-enable it someday if we can
* convince ourselves we have safe protocols for un-hooking from hook function
* pointers, releasing custom GUC variables, and perhaps other things that
* are definitely unsafe currently.
*/ */
static void static void
internal_unload_library(const char *libname) internal_unload_library(const char *libname)
{ {
#ifdef NOT_USED
DynamicFileList *file_scanner, DynamicFileList *file_scanner,
*prv, *prv,
*nxt; *nxt;
@ -436,6 +443,7 @@ internal_unload_library(const char *libname)
else else
prv = file_scanner; prv = file_scanner;
} }
#endif /* NOT_USED */
} }
static bool static bool