Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 33c6eaf

Browse files
committed
Ignore SECURITY DEFINER and SET attributes for a PL's call handler.
It's not very sensible to set such attributes on a handler function; but if one were to do so, fmgr.c went into infinite recursion because it would call fmgr_security_definer instead of the handler function proper. There is no way for fmgr_security_definer to know that it ought to call the handler and not the original function referenced by the FmgrInfo's fn_oid, so it tries to do the latter, causing the whole process to start over again. Ordinarily such misconfiguration of a procedural language's handler could be written off as superuser error. However, because we allow non-superuser database owners to create procedural languages and the handler for such a language becomes owned by the database owner, it is possible for a database owner to crash the backend, which ideally shouldn't be possible without superuser privileges. In 9.2 and up we will adjust things so that the handler functions are always owned by superusers, but in existing branches this is a minor security fix. Problem noted by Noah Misch (after several of us had failed to detect it :-(). This is CVE-2012-2655.
1 parent cd0ff9c commit 33c6eaf

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/backend/utils/fmgr/fmgr.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ fmgr_lookupByName(const char *name)
158158
void
159159
fmgr_info(Oid functionId, FmgrInfo *finfo)
160160
{
161-
fmgr_info_cxt(functionId, finfo, CurrentMemoryContext);
161+
fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false);
162162
}
163163

164164
/*
@@ -173,7 +173,7 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
173173

174174
/*
175175
* This one does the actual work. ignore_security is ordinarily false
176-
* but is set to true by fmgr_security_definer to avoid recursion.
176+
* but is set to true when we need to avoid recursion.
177177
*/
178178
static void
179179
fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
@@ -223,7 +223,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
223223
/*
224224
* If it has prosecdef set, non-null proconfig, or if a plugin wants to
225225
* hook function entry/exit, use fmgr_security_definer call handler ---
226-
* unless we are being called again by fmgr_security_definer.
226+
* unless we are being called again by fmgr_security_definer or
227+
* fmgr_info_other_lang.
227228
*
228229
* When using fmgr_security_definer, function stats tracking is always
229230
* disabled at the outer level, and instead we set the flag properly in
@@ -405,7 +406,13 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
405406
elog(ERROR, "cache lookup failed for language %u", language);
406407
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
407408

408-
fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
409+
/*
410+
* Look up the language's call handler function, ignoring any attributes
411+
* that would normally cause insertion of fmgr_security_definer. We
412+
* need to get back a bare pointer to the actual C-language function.
413+
*/
414+
fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo,
415+
CurrentMemoryContext, true);
409416
finfo->fn_addr = plfinfo.fn_addr;
410417

411418
/*

0 commit comments

Comments
 (0)