Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit377b7a8

Browse files
committed
Don't leak malloc'd strings when a GUC setting is rejected.
Because guc.c prefers to keep all its string values in malloc'dnot palloc'd storage, it has to be more careful than usual toavoid leaks. Error exits out of string GUC hook checks failedto clear the proposed value string, and error exits out ofProcessGUCArray() failed to clear the malloc'd results ofParseLongOption().Found via valgrind testing.This problem is ancient, so back-patch to all supported branches.Discussion:https://postgr.es/m/3816764.1616104288@sss.pgh.pa.us
1 parentd303849 commit377b7a8

File tree

1 file changed

+47
-24
lines changed
  • src/backend/utils/misc

1 file changed

+47
-24
lines changed

‎src/backend/utils/misc/guc.c

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10773,6 +10773,8 @@ ProcessGUCArray(ArrayType *array,
1077310773
char*s;
1077410774
char*name;
1077510775
char*value;
10776+
char*namecopy;
10777+
char*valuecopy;
1077610778

1077710779
d=array_ref(array,1,&i,
1077810780
-1/* varlenarray */ ,
@@ -10797,13 +10799,18 @@ ProcessGUCArray(ArrayType *array,
1079710799
continue;
1079810800
}
1079910801

10800-
(void)set_config_option(name,value,
10802+
/* free malloc'd strings immediately to avoid leak upon error */
10803+
namecopy=pstrdup(name);
10804+
free(name);
10805+
valuecopy=pstrdup(value);
10806+
free(value);
10807+
10808+
(void)set_config_option(namecopy,valuecopy,
1080110809
context,source,
1080210810
action, true,0, false);
1080310811

10804-
free(name);
10805-
if (value)
10806-
free(value);
10812+
pfree(namecopy);
10813+
pfree(valuecopy);
1080710814
pfree(s);
1080810815
}
1080910816
}
@@ -11235,34 +11242,50 @@ static bool
1123511242
call_string_check_hook(structconfig_string*conf,char**newval,void**extra,
1123611243
GucSourcesource,intelevel)
1123711244
{
11245+
volatileboolresult= true;
11246+
1123811247
/* Quick success if no hook */
1123911248
if (!conf->check_hook)
1124011249
return true;
1124111250

11242-
/* Reset variables that might be set by hook */
11243-
GUC_check_errcode_value=ERRCODE_INVALID_PARAMETER_VALUE;
11244-
GUC_check_errmsg_string=NULL;
11245-
GUC_check_errdetail_string=NULL;
11246-
GUC_check_errhint_string=NULL;
11251+
/*
11252+
* If elevel is ERROR, or if the check_hook itself throws an elog
11253+
* (undesirable, but not always avoidable), make sure we don't leak the
11254+
* already-malloc'd newval string.
11255+
*/
11256+
PG_TRY();
11257+
{
11258+
/* Reset variables that might be set by hook */
11259+
GUC_check_errcode_value=ERRCODE_INVALID_PARAMETER_VALUE;
11260+
GUC_check_errmsg_string=NULL;
11261+
GUC_check_errdetail_string=NULL;
11262+
GUC_check_errhint_string=NULL;
1124711263

11248-
if (!conf->check_hook(newval,extra,source))
11264+
if (!conf->check_hook(newval,extra,source))
11265+
{
11266+
ereport(elevel,
11267+
(errcode(GUC_check_errcode_value),
11268+
GUC_check_errmsg_string ?
11269+
errmsg_internal("%s",GUC_check_errmsg_string) :
11270+
errmsg("invalid value for parameter \"%s\": \"%s\"",
11271+
conf->gen.name,*newval ?*newval :""),
11272+
GUC_check_errdetail_string ?
11273+
errdetail_internal("%s",GUC_check_errdetail_string) :0,
11274+
GUC_check_errhint_string ?
11275+
errhint("%s",GUC_check_errhint_string) :0));
11276+
/* Flush any strings created in ErrorContext */
11277+
FlushErrorState();
11278+
result= false;
11279+
}
11280+
}
11281+
PG_CATCH();
1124911282
{
11250-
ereport(elevel,
11251-
(errcode(GUC_check_errcode_value),
11252-
GUC_check_errmsg_string ?
11253-
errmsg_internal("%s",GUC_check_errmsg_string) :
11254-
errmsg("invalid value for parameter \"%s\": \"%s\"",
11255-
conf->gen.name,*newval ?*newval :""),
11256-
GUC_check_errdetail_string ?
11257-
errdetail_internal("%s",GUC_check_errdetail_string) :0,
11258-
GUC_check_errhint_string ?
11259-
errhint("%s",GUC_check_errhint_string) :0));
11260-
/* Flush any strings created in ErrorContext */
11261-
FlushErrorState();
11262-
return false;
11283+
free(*newval);
11284+
PG_RE_THROW();
1126311285
}
11286+
PG_END_TRY();
1126411287

11265-
returntrue;
11288+
returnresult;
1126611289
}
1126711290

1126811291
staticbool

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp