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

Commitd136d60

Browse files
committed
Fix possible read past end of string in to_timestamp().
to_timestamp() handles the TH/th format codes by advancing over two inputcharacters, whatever those are. It failed to notice whether there weretwo characters available to be skipped, making it possible to advancethe pointer past the end of the input string and keep on parsing.A similar risk existed in the handling of "Y,YYY" format: it would advanceover three characters after the "," whether or not three characters wereavailable.In principle this might be exploitable to disclose contents of servermemory. But the security team concluded that it would be very hard to usethat way, because the parsing loop would stop upon hitting any zero byte,and TH/th format codes can't be consecutive --- they have to follow someother format code, which would have to match whatever data is there.So it seems impractical to examine memory very much beyond the end of theinput string via this bug; and the input string will always be in localmemory not in disk buffers, making it unlikely that anything veryinteresting is close to it in a predictable way. So this doesn't quiterise to the level of needing a CVE.Thanks to Wolf Roediger for reporting this bug.
1 parent6b8b4e4 commitd136d60

File tree

1 file changed

+39
-45
lines changed

1 file changed

+39
-45
lines changed

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

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,6 @@ static const char *get_th(char *num, int type);
964964
staticchar*str_numth(char*dest,char*num,inttype);
965965
staticintadjust_partial_year_to_2020(intyear);
966966
staticintstrspace_len(char*str);
967-
staticintstrdigits_len(char*str);
968967
staticvoidfrom_char_set_mode(TmFromChar*tmfc,constFromCharDateModemode);
969968
staticvoidfrom_char_set_int(int*dest,constintvalue,constFormatNode*node);
970969
staticintfrom_char_parse_int_len(int*dest,char**src,constintlen,FormatNode*node);
@@ -1976,9 +1975,19 @@ asc_toupper_z(const char *buff)
19761975

19771976
/* ----------
19781977
* Skip TM / th in FROM_CHAR
1978+
*
1979+
* If S_THth is on, skip two chars, assuming there are two available
19791980
* ----------
19801981
*/
1981-
#defineSKIP_THth(_suf)(S_THth(_suf) ? 2 : 0)
1982+
#defineSKIP_THth(ptr,_suf) \
1983+
do { \
1984+
if (S_THth(_suf)) \
1985+
{ \
1986+
if (*(ptr)) (ptr)++; \
1987+
if (*(ptr)) (ptr)++; \
1988+
} \
1989+
} while (0)
1990+
19821991

19831992
#ifdefDEBUG_TO_FROM_CHAR
19841993
/* -----------
@@ -2086,23 +2095,6 @@ strspace_len(char *str)
20862095
returnlen;
20872096
}
20882097

2089-
staticint
2090-
strdigits_len(char*str)
2091-
{
2092-
char*p=str;
2093-
intlen;
2094-
2095-
len=strspace_len(str);
2096-
p+=len;
2097-
2098-
while (*p&&isdigit((unsignedchar)*p)&&len <=DCH_MAX_ITEM_SIZ)
2099-
{
2100-
len++;
2101-
p++;
2102-
}
2103-
returnlen;
2104-
}
2105-
21062098
/*
21072099
* Set the date mode of a from-char conversion.
21082100
*
@@ -3007,19 +2999,19 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30072999
caseDCH_HH12:
30083000
from_char_parse_int_len(&out->hh,&s,2,n);
30093001
out->clock=CLOCK_12_HOUR;
3010-
s+=SKIP_THth(n->suffix);
3002+
SKIP_THth(s,n->suffix);
30113003
break;
30123004
caseDCH_HH24:
30133005
from_char_parse_int_len(&out->hh,&s,2,n);
3014-
s+=SKIP_THth(n->suffix);
3006+
SKIP_THth(s,n->suffix);
30153007
break;
30163008
caseDCH_MI:
30173009
from_char_parse_int(&out->mi,&s,n);
3018-
s+=SKIP_THth(n->suffix);
3010+
SKIP_THth(s,n->suffix);
30193011
break;
30203012
caseDCH_SS:
30213013
from_char_parse_int(&out->ss,&s,n);
3022-
s+=SKIP_THth(n->suffix);
3014+
SKIP_THth(s,n->suffix);
30233015
break;
30243016
caseDCH_MS:/* millisecond */
30253017
len=from_char_parse_int_len(&out->ms,&s,3,n);
@@ -3030,7 +3022,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30303022
out->ms *=len==1 ?100 :
30313023
len==2 ?10 :1;
30323024

3033-
s+=SKIP_THth(n->suffix);
3025+
SKIP_THth(s,n->suffix);
30343026
break;
30353027
caseDCH_US:/* microsecond */
30363028
len=from_char_parse_int_len(&out->us,&s,6,n);
@@ -3041,11 +3033,11 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30413033
len==4 ?100 :
30423034
len==5 ?10 :1;
30433035

3044-
s+=SKIP_THth(n->suffix);
3036+
SKIP_THth(s,n->suffix);
30453037
break;
30463038
caseDCH_SSSS:
30473039
from_char_parse_int(&out->ssss,&s,n);
3048-
s+=SKIP_THth(n->suffix);
3040+
SKIP_THth(s,n->suffix);
30493041
break;
30503042
caseDCH_tz:
30513043
caseDCH_TZ:
@@ -3085,7 +3077,7 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
30853077
break;
30863078
caseDCH_MM:
30873079
from_char_parse_int(&out->mm,&s,n);
3088-
s+=SKIP_THth(n->suffix);
3080+
SKIP_THth(s,n->suffix);
30893081
break;
30903082
caseDCH_DAY:
30913083
caseDCH_Day:
@@ -3105,31 +3097,31 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
31053097
break;
31063098
caseDCH_DDD:
31073099
from_char_parse_int(&out->ddd,&s,n);
3108-
s+=SKIP_THth(n->suffix);
3100+
SKIP_THth(s,n->suffix);
31093101
break;
31103102
caseDCH_IDDD:
31113103
from_char_parse_int_len(&out->ddd,&s,3,n);
3112-
s+=SKIP_THth(n->suffix);
3104+
SKIP_THth(s,n->suffix);
31133105
break;
31143106
caseDCH_DD:
31153107
from_char_parse_int(&out->dd,&s,n);
3116-
s+=SKIP_THth(n->suffix);
3108+
SKIP_THth(s,n->suffix);
31173109
break;
31183110
caseDCH_D:
31193111
from_char_parse_int(&out->d,&s,n);
3120-
s+=SKIP_THth(n->suffix);
3112+
SKIP_THth(s,n->suffix);
31213113
break;
31223114
caseDCH_ID:
31233115
from_char_parse_int_len(&out->d,&s,1,n);
31243116
/* Shift numbering to match Gregorian where Sunday = 1 */
31253117
if (++out->d>7)
31263118
out->d=1;
3127-
s+=SKIP_THth(n->suffix);
3119+
SKIP_THth(s,n->suffix);
31283120
break;
31293121
caseDCH_WW:
31303122
caseDCH_IW:
31313123
from_char_parse_int(&out->ww,&s,n);
3132-
s+=SKIP_THth(n->suffix);
3124+
SKIP_THth(s,n->suffix);
31333125
break;
31343126
caseDCH_Q:
31353127

@@ -3144,55 +3136,57 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
31443136
* isn't stored anywhere in 'out'.
31453137
*/
31463138
from_char_parse_int((int*)NULL,&s,n);
3147-
s+=SKIP_THth(n->suffix);
3139+
SKIP_THth(s,n->suffix);
31483140
break;
31493141
caseDCH_CC:
31503142
from_char_parse_int(&out->cc,&s,n);
3151-
s+=SKIP_THth(n->suffix);
3143+
SKIP_THth(s,n->suffix);
31523144
break;
31533145
caseDCH_Y_YYY:
31543146
{
31553147
intmatched,
31563148
years,
3157-
millenia;
3149+
millenia,
3150+
nch;
31583151

3159-
matched=sscanf(s,"%d,%03d",&millenia,&years);
3160-
if (matched!=2)
3152+
matched=sscanf(s,"%d,%03d%n",&millenia,&years,&nch);
3153+
if (matched<2)
31613154
ereport(ERROR,
31623155
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
31633156
errmsg("invalid input string for \"Y,YYY\"")));
31643157
years+= (millenia*1000);
31653158
from_char_set_int(&out->year,years,n);
31663159
out->yysz=4;
3167-
s+=strdigits_len(s)+4+SKIP_THth(n->suffix);
3160+
s+=nch;
3161+
SKIP_THth(s,n->suffix);
31683162
}
31693163
break;
31703164
caseDCH_YYYY:
31713165
caseDCH_IYYY:
31723166
from_char_parse_int(&out->year,&s,n);
31733167
out->yysz=4;
3174-
s+=SKIP_THth(n->suffix);
3168+
SKIP_THth(s,n->suffix);
31753169
break;
31763170
caseDCH_YYY:
31773171
caseDCH_IYY:
31783172
if (from_char_parse_int(&out->year,&s,n)<4)
31793173
out->year=adjust_partial_year_to_2020(out->year);
31803174
out->yysz=3;
3181-
s+=SKIP_THth(n->suffix);
3175+
SKIP_THth(s,n->suffix);
31823176
break;
31833177
caseDCH_YY:
31843178
caseDCH_IY:
31853179
if (from_char_parse_int(&out->year,&s,n)<4)
31863180
out->year=adjust_partial_year_to_2020(out->year);
31873181
out->yysz=2;
3188-
s+=SKIP_THth(n->suffix);
3182+
SKIP_THth(s,n->suffix);
31893183
break;
31903184
caseDCH_Y:
31913185
caseDCH_I:
31923186
if (from_char_parse_int(&out->year,&s,n)<4)
31933187
out->year=adjust_partial_year_to_2020(out->year);
31943188
out->yysz=1;
3195-
s+=SKIP_THth(n->suffix);
3189+
SKIP_THth(s,n->suffix);
31963190
break;
31973191
caseDCH_RM:
31983192
from_char_seq_search(&value,&s,rm_months_upper,
@@ -3206,11 +3200,11 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
32063200
break;
32073201
caseDCH_W:
32083202
from_char_parse_int(&out->w,&s,n);
3209-
s+=SKIP_THth(n->suffix);
3203+
SKIP_THth(s,n->suffix);
32103204
break;
32113205
caseDCH_J:
32123206
from_char_parse_int(&out->j,&s,n);
3213-
s+=SKIP_THth(n->suffix);
3207+
SKIP_THth(s,n->suffix);
32143208
break;
32153209
}
32163210
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp