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

Commit56b970f

Browse files
committed
to_char(): prevent writing beyond the allocated buffer
Previously very long localized month and weekday strings couldoverflow the allocated buffers, causing a server crash.Reported and patch reviewed by Noah Misch. Backpatch to allsupported versions.Security:CVE-2015-0241
1 parent611e110 commit56b970f

File tree

1 file changed

+126
-15
lines changed

1 file changed

+126
-15
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 126 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
* Maximal length of one node
110110
* ----------
111111
*/
112-
#defineDCH_MAX_ITEM_SIZ9/* maxjulian day*/
112+
#defineDCH_MAX_ITEM_SIZ 12/* maxlocalized day name*/
113113
#defineNUM_MAX_ITEM_SIZ8/* roman number (RN has 15 chars)*/
114114

115115
/* ----------
@@ -524,10 +524,12 @@ do { \
524524
* Suffixes definition for DATE-TIME TO/FROM CHAR
525525
* ----------
526526
*/
527+
#defineTM_SUFFIX_LEN2
528+
527529
staticKeySuffixDCH_suff[]= {
528530
{"FM",2,DCH_S_FM,SUFFTYPE_PREFIX},
529531
{"fm",2,DCH_S_FM,SUFFTYPE_PREFIX},
530-
{"TM",2,DCH_S_TM,SUFFTYPE_PREFIX},
532+
{"TM",TM_SUFFIX_LEN,DCH_S_TM,SUFFTYPE_PREFIX},
531533
{"tm",2,DCH_S_TM,SUFFTYPE_PREFIX},
532534
{"TH",2,DCH_S_TH,SUFFTYPE_POSTFIX},
533535
{"th",2,DCH_S_th,SUFFTYPE_POSTFIX},
@@ -536,6 +538,7 @@ static KeySuffix DCH_suff[] = {
536538
{NULL,0,0,0}
537539
};
538540

541+
539542
/* ----------
540543
* Format-pictures (KeyWord).
541544
*
@@ -2292,18 +2295,36 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
22922295
if (!tm->tm_mon)
22932296
break;
22942297
if (S_TM(n->suffix))
2295-
strcpy(s,str_toupper_z(localized_full_months[tm->tm_mon-1]));
2298+
{
2299+
char*str=str_toupper_z(localized_full_months[tm->tm_mon-1]);
2300+
2301+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2302+
strcpy(s,str);
2303+
else
2304+
ereport(ERROR,
2305+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2306+
errmsg("localized string format value too long")));
2307+
}
22962308
else
22972309
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
2298-
asc_toupper_z(months_full[tm->tm_mon-1]));
2310+
asc_toupper_z(months_full[tm->tm_mon-1]));
22992311
s+=strlen(s);
23002312
break;
23012313
caseDCH_Month:
23022314
INVALID_FOR_INTERVAL;
23032315
if (!tm->tm_mon)
23042316
break;
23052317
if (S_TM(n->suffix))
2306-
strcpy(s,str_initcap_z(localized_full_months[tm->tm_mon-1]));
2318+
{
2319+
char*str=str_initcap_z(localized_full_months[tm->tm_mon-1]);
2320+
2321+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2322+
strcpy(s,str);
2323+
else
2324+
ereport(ERROR,
2325+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2326+
errmsg("localized string format value too long")));
2327+
}
23072328
else
23082329
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
23092330
months_full[tm->tm_mon-1]);
@@ -2314,7 +2335,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23142335
if (!tm->tm_mon)
23152336
break;
23162337
if (S_TM(n->suffix))
2317-
strcpy(s,str_tolower_z(localized_full_months[tm->tm_mon-1]));
2338+
{
2339+
char*str=str_tolower_z(localized_full_months[tm->tm_mon-1]);
2340+
2341+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2342+
strcpy(s,str);
2343+
else
2344+
ereport(ERROR,
2345+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2346+
errmsg("localized string format value too long")));
2347+
}
23182348
else
23192349
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
23202350
asc_tolower_z(months_full[tm->tm_mon-1]));
@@ -2325,7 +2355,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23252355
if (!tm->tm_mon)
23262356
break;
23272357
if (S_TM(n->suffix))
2328-
strcpy(s,str_toupper_z(localized_abbrev_months[tm->tm_mon-1]));
2358+
{
2359+
char*str=str_toupper_z(localized_abbrev_months[tm->tm_mon-1]);
2360+
2361+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2362+
strcpy(s,str);
2363+
else
2364+
ereport(ERROR,
2365+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2366+
errmsg("localized string format value too long")));
2367+
}
23292368
else
23302369
strcpy(s,asc_toupper_z(months[tm->tm_mon-1]));
23312370
s+=strlen(s);
@@ -2335,7 +2374,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23352374
if (!tm->tm_mon)
23362375
break;
23372376
if (S_TM(n->suffix))
2338-
strcpy(s,str_initcap_z(localized_abbrev_months[tm->tm_mon-1]));
2377+
{
2378+
char*str=str_initcap_z(localized_abbrev_months[tm->tm_mon-1]);
2379+
2380+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2381+
strcpy(s,str);
2382+
else
2383+
ereport(ERROR,
2384+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2385+
errmsg("localized string format value too long")));
2386+
}
23392387
else
23402388
strcpy(s,months[tm->tm_mon-1]);
23412389
s+=strlen(s);
@@ -2345,7 +2393,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23452393
if (!tm->tm_mon)
23462394
break;
23472395
if (S_TM(n->suffix))
2348-
strcpy(s,str_tolower_z(localized_abbrev_months[tm->tm_mon-1]));
2396+
{
2397+
char*str=str_tolower_z(localized_abbrev_months[tm->tm_mon-1]);
2398+
2399+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2400+
strcpy(s,str);
2401+
else
2402+
ereport(ERROR,
2403+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2404+
errmsg("localized string format value too long")));
2405+
}
23492406
else
23502407
strcpy(s,asc_tolower_z(months[tm->tm_mon-1]));
23512408
s+=strlen(s);
@@ -2359,7 +2416,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23592416
caseDCH_DAY:
23602417
INVALID_FOR_INTERVAL;
23612418
if (S_TM(n->suffix))
2362-
strcpy(s,str_toupper_z(localized_full_days[tm->tm_wday]));
2419+
{
2420+
char*str=str_toupper_z(localized_full_days[tm->tm_wday]);
2421+
2422+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2423+
strcpy(s,str);
2424+
else
2425+
ereport(ERROR,
2426+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2427+
errmsg("localized string format value too long")));
2428+
}
23632429
else
23642430
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
23652431
asc_toupper_z(days[tm->tm_wday]));
@@ -2368,7 +2434,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23682434
caseDCH_Day:
23692435
INVALID_FOR_INTERVAL;
23702436
if (S_TM(n->suffix))
2371-
strcpy(s,str_initcap_z(localized_full_days[tm->tm_wday]));
2437+
{
2438+
char*str=str_initcap_z(localized_full_days[tm->tm_wday]);
2439+
2440+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2441+
strcpy(s,str);
2442+
else
2443+
ereport(ERROR,
2444+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2445+
errmsg("localized string format value too long")));
2446+
}
23722447
else
23732448
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
23742449
days[tm->tm_wday]);
@@ -2377,7 +2452,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23772452
caseDCH_day:
23782453
INVALID_FOR_INTERVAL;
23792454
if (S_TM(n->suffix))
2380-
strcpy(s,str_tolower_z(localized_full_days[tm->tm_wday]));
2455+
{
2456+
char*str=str_tolower_z(localized_full_days[tm->tm_wday]);
2457+
2458+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2459+
strcpy(s,str);
2460+
else
2461+
ereport(ERROR,
2462+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2463+
errmsg("localized string format value too long")));
2464+
}
23812465
else
23822466
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
23832467
asc_tolower_z(days[tm->tm_wday]));
@@ -2386,23 +2470,50 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
23862470
caseDCH_DY:
23872471
INVALID_FOR_INTERVAL;
23882472
if (S_TM(n->suffix))
2389-
strcpy(s,str_toupper_z(localized_abbrev_days[tm->tm_wday]));
2473+
{
2474+
char*str=str_toupper_z(localized_abbrev_days[tm->tm_wday]);
2475+
2476+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2477+
strcpy(s,str);
2478+
else
2479+
ereport(ERROR,
2480+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2481+
errmsg("localized string format value too long")));
2482+
}
23902483
else
23912484
strcpy(s,asc_toupper_z(days_short[tm->tm_wday]));
23922485
s+=strlen(s);
23932486
break;
23942487
caseDCH_Dy:
23952488
INVALID_FOR_INTERVAL;
23962489
if (S_TM(n->suffix))
2397-
strcpy(s,str_initcap_z(localized_abbrev_days[tm->tm_wday]));
2490+
{
2491+
char*str=str_initcap_z(localized_abbrev_days[tm->tm_wday]);
2492+
2493+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2494+
strcpy(s,str);
2495+
else
2496+
ereport(ERROR,
2497+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2498+
errmsg("localized string format value too long")));
2499+
}
23982500
else
23992501
strcpy(s,days_short[tm->tm_wday]);
24002502
s+=strlen(s);
24012503
break;
24022504
caseDCH_dy:
24032505
INVALID_FOR_INTERVAL;
24042506
if (S_TM(n->suffix))
2405-
strcpy(s,str_tolower_z(localized_abbrev_days[tm->tm_wday]));
2507+
{
2508+
char*str=str_tolower_z(localized_abbrev_days[tm->tm_wday]);
2509+
2510+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2511+
strcpy(s,str);
2512+
else
2513+
ereport(ERROR,
2514+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2515+
errmsg("localized string format value too long")));
2516+
}
24062517
else
24072518
strcpy(s,asc_tolower_z(days_short[tm->tm_wday]));
24082519
s+=strlen(s);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp