Do not overallocate on the stack. Threaded code might use custom stack

size.

Reported by:	many
Tested by:	Jeremie Le Hen <jeremie@le-hen.org> (previous version)
Reviewed by:	jilles
Approved by:	re (bz)
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2011-09-19 22:35:54 +00:00
parent 87eac1ceb9
commit 8046e2fda0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225677

View File

@ -380,13 +380,16 @@ register const int doextend;
int fid; int fid;
int stored; int stored;
int nread; int nread;
int res;
union { union {
struct tzhead tzhead; struct tzhead tzhead;
char buf[2 * sizeof(struct tzhead) + char buf[2 * sizeof(struct tzhead) +
2 * sizeof *sp + 2 * sizeof *sp +
4 * TZ_MAX_TIMES]; 4 * TZ_MAX_TIMES];
} u; } *u;
u = NULL;
res = -1;
sp->goback = sp->goahead = FALSE; sp->goback = sp->goahead = FALSE;
/* XXX The following is from OpenBSD, and I'm not sure it is correct */ /* XXX The following is from OpenBSD, and I'm not sure it is correct */
@ -406,16 +409,24 @@ register const int doextend;
** to hold the longest file name string that the implementation ** to hold the longest file name string that the implementation
** guarantees can be opened." ** guarantees can be opened."
*/ */
char fullname[FILENAME_MAX + 1]; char *fullname;
fullname = malloc(FILENAME_MAX + 1);
if (fullname == NULL)
goto out;
if (name[0] == ':') if (name[0] == ':')
++name; ++name;
doaccess = name[0] == '/'; doaccess = name[0] == '/';
if (!doaccess) { if (!doaccess) {
if ((p = TZDIR) == NULL) if ((p = TZDIR) == NULL) {
free(fullname);
return -1; return -1;
if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname) }
if (strlen(p) + 1 + strlen(name) >= FILENAME_MAX) {
free(fullname);
return -1; return -1;
}
(void) strcpy(fullname, p); (void) strcpy(fullname, p);
(void) strcat(fullname, "/"); (void) strcat(fullname, "/");
(void) strcat(fullname, name); (void) strcat(fullname, name);
@ -426,37 +437,45 @@ register const int doextend;
doaccess = TRUE; doaccess = TRUE;
name = fullname; name = fullname;
} }
if (doaccess && access(name, R_OK) != 0) if (doaccess && access(name, R_OK) != 0) {
free(fullname);
return -1; return -1;
if ((fid = _open(name, OPEN_MODE)) == -1) }
if ((fid = _open(name, OPEN_MODE)) == -1) {
free(fullname);
return -1; return -1;
}
if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) { if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
free(fullname);
_close(fid); _close(fid);
return -1; return -1;
} }
} }
nread = _read(fid, u.buf, sizeof u.buf); u = malloc(sizeof(*u));
if (u == NULL)
goto out;
nread = _read(fid, u->buf, sizeof u->buf);
if (_close(fid) < 0 || nread <= 0) if (_close(fid) < 0 || nread <= 0)
return -1; goto out;
for (stored = 4; stored <= 8; stored *= 2) { for (stored = 4; stored <= 8; stored *= 2) {
int ttisstdcnt; int ttisstdcnt;
int ttisgmtcnt; int ttisgmtcnt;
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); ttisstdcnt = (int) detzcode(u->tzhead.tzh_ttisstdcnt);
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); ttisgmtcnt = (int) detzcode(u->tzhead.tzh_ttisgmtcnt);
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt); sp->leapcnt = (int) detzcode(u->tzhead.tzh_leapcnt);
sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt); sp->timecnt = (int) detzcode(u->tzhead.tzh_timecnt);
sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt); sp->typecnt = (int) detzcode(u->tzhead.tzh_typecnt);
sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt); sp->charcnt = (int) detzcode(u->tzhead.tzh_charcnt);
p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt; p = u->tzhead.tzh_charcnt + sizeof u->tzhead.tzh_charcnt;
if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
return -1; goto out;
if (nread - (p - u.buf) < if (nread - (p - u->buf) <
sp->timecnt * stored + /* ats */ sp->timecnt * stored + /* ats */
sp->timecnt + /* types */ sp->timecnt + /* types */
sp->typecnt * 6 + /* ttinfos */ sp->typecnt * 6 + /* ttinfos */
@ -464,7 +483,7 @@ register const int doextend;
sp->leapcnt * (stored + 4) + /* lsinfos */ sp->leapcnt * (stored + 4) + /* lsinfos */
ttisstdcnt + /* ttisstds */ ttisstdcnt + /* ttisstds */
ttisgmtcnt) /* ttisgmts */ ttisgmtcnt) /* ttisgmts */
return -1; goto out;
for (i = 0; i < sp->timecnt; ++i) { for (i = 0; i < sp->timecnt; ++i) {
sp->ats[i] = (stored == 4) ? sp->ats[i] = (stored == 4) ?
detzcode(p) : detzcode64(p); detzcode(p) : detzcode64(p);
@ -473,7 +492,7 @@ register const int doextend;
for (i = 0; i < sp->timecnt; ++i) { for (i = 0; i < sp->timecnt; ++i) {
sp->types[i] = (unsigned char) *p++; sp->types[i] = (unsigned char) *p++;
if (sp->types[i] >= sp->typecnt) if (sp->types[i] >= sp->typecnt)
return -1; goto out;
} }
for (i = 0; i < sp->typecnt; ++i) { for (i = 0; i < sp->typecnt; ++i) {
struct ttinfo * ttisp; struct ttinfo * ttisp;
@ -483,11 +502,11 @@ register const int doextend;
p += 4; p += 4;
ttisp->tt_isdst = (unsigned char) *p++; ttisp->tt_isdst = (unsigned char) *p++;
if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
return -1; goto out;
ttisp->tt_abbrind = (unsigned char) *p++; ttisp->tt_abbrind = (unsigned char) *p++;
if (ttisp->tt_abbrind < 0 || if (ttisp->tt_abbrind < 0 ||
ttisp->tt_abbrind > sp->charcnt) ttisp->tt_abbrind > sp->charcnt)
return -1; goto out;
} }
for (i = 0; i < sp->charcnt; ++i) for (i = 0; i < sp->charcnt; ++i)
sp->chars[i] = *p++; sp->chars[i] = *p++;
@ -512,7 +531,7 @@ register const int doextend;
ttisp->tt_ttisstd = *p++; ttisp->tt_ttisstd = *p++;
if (ttisp->tt_ttisstd != TRUE && if (ttisp->tt_ttisstd != TRUE &&
ttisp->tt_ttisstd != FALSE) ttisp->tt_ttisstd != FALSE)
return -1; goto out;
} }
} }
for (i = 0; i < sp->typecnt; ++i) { for (i = 0; i < sp->typecnt; ++i) {
@ -525,7 +544,7 @@ register const int doextend;
ttisp->tt_ttisgmt = *p++; ttisp->tt_ttisgmt = *p++;
if (ttisp->tt_ttisgmt != TRUE && if (ttisp->tt_ttisgmt != TRUE &&
ttisp->tt_ttisgmt != FALSE) ttisp->tt_ttisgmt != FALSE)
return -1; goto out;
} }
} }
/* /*
@ -558,11 +577,11 @@ register const int doextend;
/* /*
** If this is an old file, we're done. ** If this is an old file, we're done.
*/ */
if (u.tzhead.tzh_version[0] == '\0') if (u->tzhead.tzh_version[0] == '\0')
break; break;
nread -= p - u.buf; nread -= p - u->buf;
for (i = 0; i < nread; ++i) for (i = 0; i < nread; ++i)
u.buf[i] = p[i]; u->buf[i] = p[i];
/* /*
** If this is a narrow integer time_t system, we're done. ** If this is a narrow integer time_t system, we're done.
*/ */
@ -570,39 +589,43 @@ register const int doextend;
break; break;
} }
if (doextend && nread > 2 && if (doextend && nread > 2 &&
u.buf[0] == '\n' && u.buf[nread - 1] == '\n' && u->buf[0] == '\n' && u->buf[nread - 1] == '\n' &&
sp->typecnt + 2 <= TZ_MAX_TYPES) { sp->typecnt + 2 <= TZ_MAX_TYPES) {
struct state ts; struct state *ts;
register int result; register int result;
u.buf[nread - 1] = '\0'; ts = malloc(sizeof(*ts));
result = tzparse(&u.buf[1], &ts, FALSE); if (ts == NULL)
if (result == 0 && ts.typecnt == 2 && goto out;
sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) { u->buf[nread - 1] = '\0';
result = tzparse(&u->buf[1], ts, FALSE);
if (result == 0 && ts->typecnt == 2 &&
sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) {
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
ts.ttis[i].tt_abbrind += ts->ttis[i].tt_abbrind +=
sp->charcnt; sp->charcnt;
for (i = 0; i < ts.charcnt; ++i) for (i = 0; i < ts->charcnt; ++i)
sp->chars[sp->charcnt++] = sp->chars[sp->charcnt++] =
ts.chars[i]; ts->chars[i];
i = 0; i = 0;
while (i < ts.timecnt && while (i < ts->timecnt &&
ts.ats[i] <= ts->ats[i] <=
sp->ats[sp->timecnt - 1]) sp->ats[sp->timecnt - 1])
++i; ++i;
while (i < ts.timecnt && while (i < ts->timecnt &&
sp->timecnt < TZ_MAX_TIMES) { sp->timecnt < TZ_MAX_TIMES) {
sp->ats[sp->timecnt] = sp->ats[sp->timecnt] =
ts.ats[i]; ts->ats[i];
sp->types[sp->timecnt] = sp->types[sp->timecnt] =
sp->typecnt + sp->typecnt +
ts.types[i]; ts->types[i];
++sp->timecnt; ++sp->timecnt;
++i; ++i;
} }
sp->ttis[sp->typecnt++] = ts.ttis[0]; sp->ttis[sp->typecnt++] = ts->ttis[0];
sp->ttis[sp->typecnt++] = ts.ttis[1]; sp->ttis[sp->typecnt++] = ts->ttis[1];
} }
free(ts);
} }
if (sp->timecnt > 1) { if (sp->timecnt > 1) {
for (i = 1; i < sp->timecnt; ++i) for (i = 1; i < sp->timecnt; ++i)
@ -620,7 +643,10 @@ register const int doextend;
break; break;
} }
} }
return 0; res = 0;
out:
free(u);
return (res);
} }
static int static int