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

Commitfc552f8

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 parent92bc14a commitfc552f8

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
@@ -10361,6 +10361,8 @@ ProcessGUCArray(ArrayType *array,
1036110361
char*s;
1036210362
char*name;
1036310363
char*value;
10364+
char*namecopy;
10365+
char*valuecopy;
1036410366

1036510367
d=array_ref(array,1,&i,
1036610368
-1/* varlenarray */ ,
@@ -10385,13 +10387,18 @@ ProcessGUCArray(ArrayType *array,
1038510387
continue;
1038610388
}
1038710389

10388-
(void)set_config_option(name,value,
10390+
/* free malloc'd strings immediately to avoid leak upon error */
10391+
namecopy=pstrdup(name);
10392+
free(name);
10393+
valuecopy=pstrdup(value);
10394+
free(value);
10395+
10396+
(void)set_config_option(namecopy,valuecopy,
1038910397
context,source,
1039010398
action, true,0, false);
1039110399

10392-
free(name);
10393-
if (value)
10394-
free(value);
10400+
pfree(namecopy);
10401+
pfree(valuecopy);
1039510402
pfree(s);
1039610403
}
1039710404
}
@@ -10823,34 +10830,50 @@ static bool
1082310830
call_string_check_hook(structconfig_string*conf,char**newval,void**extra,
1082410831
GucSourcesource,intelevel)
1082510832
{
10833+
volatileboolresult= true;
10834+
1082610835
/* Quick success if no hook */
1082710836
if (!conf->check_hook)
1082810837
return true;
1082910838

10830-
/* Reset variables that might be set by hook */
10831-
GUC_check_errcode_value=ERRCODE_INVALID_PARAMETER_VALUE;
10832-
GUC_check_errmsg_string=NULL;
10833-
GUC_check_errdetail_string=NULL;
10834-
GUC_check_errhint_string=NULL;
10839+
/*
10840+
* If elevel is ERROR, or if the check_hook itself throws an elog
10841+
* (undesirable, but not always avoidable), make sure we don't leak the
10842+
* already-malloc'd newval string.
10843+
*/
10844+
PG_TRY();
10845+
{
10846+
/* Reset variables that might be set by hook */
10847+
GUC_check_errcode_value=ERRCODE_INVALID_PARAMETER_VALUE;
10848+
GUC_check_errmsg_string=NULL;
10849+
GUC_check_errdetail_string=NULL;
10850+
GUC_check_errhint_string=NULL;
1083510851

10836-
if (!conf->check_hook(newval,extra,source))
10852+
if (!conf->check_hook(newval,extra,source))
10853+
{
10854+
ereport(elevel,
10855+
(errcode(GUC_check_errcode_value),
10856+
GUC_check_errmsg_string ?
10857+
errmsg_internal("%s",GUC_check_errmsg_string) :
10858+
errmsg("invalid value for parameter \"%s\": \"%s\"",
10859+
conf->gen.name,*newval ?*newval :""),
10860+
GUC_check_errdetail_string ?
10861+
errdetail_internal("%s",GUC_check_errdetail_string) :0,
10862+
GUC_check_errhint_string ?
10863+
errhint("%s",GUC_check_errhint_string) :0));
10864+
/* Flush any strings created in ErrorContext */
10865+
FlushErrorState();
10866+
result= false;
10867+
}
10868+
}
10869+
PG_CATCH();
1083710870
{
10838-
ereport(elevel,
10839-
(errcode(GUC_check_errcode_value),
10840-
GUC_check_errmsg_string ?
10841-
errmsg_internal("%s",GUC_check_errmsg_string) :
10842-
errmsg("invalid value for parameter \"%s\": \"%s\"",
10843-
conf->gen.name,*newval ?*newval :""),
10844-
GUC_check_errdetail_string ?
10845-
errdetail_internal("%s",GUC_check_errdetail_string) :0,
10846-
GUC_check_errhint_string ?
10847-
errhint("%s",GUC_check_errhint_string) :0));
10848-
/* Flush any strings created in ErrorContext */
10849-
FlushErrorState();
10850-
return false;
10871+
free(*newval);
10872+
PG_RE_THROW();
1085110873
}
10874+
PG_END_TRY();
1085210875

10853-
returntrue;
10876+
returnresult;
1085410877
}
1085510878

1085610879
staticbool

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp