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

Commit fbcc69c

Browse files
committed
Prevent integer overflows during units conversion when displaying a GUC
variable that has units. Per report from Stefan Kaltenbrunner. Backport to 8.2. I also backported my patch of 2007-06-21 that prevented comparable overflows on the input side, since that now seems to have enough field track record to be back-patched safely. That patch included addition of hints listing the available unit names, which I did not bother to strip out of it --- this will make a little more work for the translators, but they can copy the translation from 8.3, and anyway an untranslated hint is better than no hint.
1 parent 2a59b79 commit fbcc69c

File tree

1 file changed

+25
-16
lines changed
  • src/backend/utils/misc

1 file changed

+25
-16
lines changed

src/backend/utils/misc/guc.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.461 2008/07/01 21:07:33 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.462 2008/07/06 19:48:45 tgl Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -6266,10 +6266,18 @@ _ShowOption(struct config_generic * record, bool use_units)
62666266
val = (*conf->show_hook) ();
62676267
else
62686268
{
6269-
char unit[4];
6270-
int result = *conf->variable;
6269+
/*
6270+
* Use int64 arithmetic to avoid overflows in units
6271+
* conversion. If INT64_IS_BUSTED we might overflow
6272+
* anyway and print bogus answers, but there are few
6273+
* enough such machines that it doesn't seem worth
6274+
* trying harder.
6275+
*/
6276+
int64 result = *conf->variable;
6277+
const char *unit;
62716278

6272-
if (use_units && result > 0 && (record->flags & GUC_UNIT_MEMORY))
6279+
if (use_units && result > 0 &&
6280+
(record->flags & GUC_UNIT_MEMORY))
62736281
{
62746282
switch (record->flags & GUC_UNIT_MEMORY)
62756283
{
@@ -6284,19 +6292,20 @@ _ShowOption(struct config_generic * record, bool use_units)
62846292
if (result % KB_PER_GB == 0)
62856293
{
62866294
result /= KB_PER_GB;
6287-
strcpy(unit, "GB");
6295+
unit = "GB";
62886296
}
62896297
else if (result % KB_PER_MB == 0)
62906298
{
62916299
result /= KB_PER_MB;
6292-
strcpy(unit, "MB");
6300+
unit = "MB";
62936301
}
62946302
else
62956303
{
6296-
strcpy(unit, "kB");
6304+
unit = "kB";
62976305
}
62986306
}
6299-
else if (use_units && result > 0 && (record->flags & GUC_UNIT_TIME))
6307+
else if (use_units && result > 0 &&
6308+
(record->flags & GUC_UNIT_TIME))
63006309
{
63016310
switch (record->flags & GUC_UNIT_TIME)
63026311
{
@@ -6311,33 +6320,33 @@ _ShowOption(struct config_generic * record, bool use_units)
63116320
if (result % MS_PER_D == 0)
63126321
{
63136322
result /= MS_PER_D;
6314-
strcpy(unit, "d");
6323+
unit = "d";
63156324
}
63166325
else if (result % MS_PER_H == 0)
63176326
{
63186327
result /= MS_PER_H;
6319-
strcpy(unit, "h");
6328+
unit = "h";
63206329
}
63216330
else if (result % MS_PER_MIN == 0)
63226331
{
63236332
result /= MS_PER_MIN;
6324-
strcpy(unit, "min");
6333+
unit = "min";
63256334
}
63266335
else if (result % MS_PER_S == 0)
63276336
{
63286337
result /= MS_PER_S;
6329-
strcpy(unit, "s");
6338+
unit = "s";
63306339
}
63316340
else
63326341
{
6333-
strcpy(unit, "ms");
6342+
unit = "ms";
63346343
}
63356344
}
63366345
else
6337-
strcpy(unit, "");
6346+
unit = "";
63386347

6339-
snprintf(buffer, sizeof(buffer), "%d%s",
6340-
(int) result, unit);
6348+
snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
6349+
result, unit);
63416350
val = buffer;
63426351
}
63436352
}

0 commit comments

Comments
 (0)