FW: stack overflow in tzload
walter harms
wharms at bfs.de
Wed Nov 24 16:38:42 UTC 2010
what si about using alloc() ?
System that do not provied it can use malloc,
others will use the stack but we will take the stack only when
needed and get an error (hopefully) when oom.
re,
wh
Am 23.11.2010 00:56, schrieb Olson, Arthur David (NIH/NCI) [E]:
> I'm forwarding this message from Ted Unangst, who is not on the time zone mailing list. Those of you who are on the list, please direct replies appropriately.
>
> --ado
>
> -----Original Message-----
> From: Ted Unangst [mailto:ted.unangst at gmail.com]
> Sent: Monday, November 22, 2010 6:22
> To: tz at lecserver.nci.nih.gov
> Subject: stack overflow in tzload
>
> Stack overflow as in there's not enough stack. I ran into this problem
> running a program on openbsd that was using a fairly small thread size. I
> switched to using malloc.
>
> Index: localtime.c
> ===================================================================
> RCS file: /home/tedu/cvs/src/lib/libc/time/localtime.c,v
> retrieving revision 1.35
> diff -u -r1.35 localtime.c
> --- localtime.c 23 Aug 2010 22:35:34 -0000 1.35
> +++ localtime.c 20 Nov 2010 23:32:09 -0000
> @@ -340,7 +340,7 @@
> char buf[2 * sizeof(struct tzhead) +
> 2 * sizeof *sp +
> 4 * TZ_MAX_TIMES];
> - } u;
> + } *u;
>
> sp->goback = sp->goahead = FALSE;
> if (name != NULL && issetugid() != 0)
> @@ -383,28 +383,33 @@
> if ((fid = open(name, OPEN_MODE)) == -1)
> return -1;
> }
> - nread = read(fid, u.buf, sizeof u.buf);
> - if (close(fid) < 0 || nread <= 0)
> + u = malloc(sizeof(*u));
> + if (!u) {
> + close(fid);
> return -1;
> + }
> + nread = read(fid, u->buf, sizeof u->buf);
> + if (close(fid) < 0 || nread <= 0)
> + goto bad;
> for (stored = 4; stored <= 8; stored *= 2) {
> int ttisstdcnt;
> int ttisgmtcnt;
>
> - ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
> - ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
> - sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
> - sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
> - sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
> - sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
> - p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
> + ttisstdcnt = (int) detzcode(u->tzhead.tzh_ttisstdcnt);
> + ttisgmtcnt = (int) detzcode(u->tzhead.tzh_ttisgmtcnt);
> + sp->leapcnt = (int) detzcode(u->tzhead.tzh_leapcnt);
> + sp->timecnt = (int) detzcode(u->tzhead.tzh_timecnt);
> + sp->typecnt = (int) detzcode(u->tzhead.tzh_typecnt);
> + sp->charcnt = (int) detzcode(u->tzhead.tzh_charcnt);
> + p = u->tzhead.tzh_charcnt + sizeof u->tzhead.tzh_charcnt;
> if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
> sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
> sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
> sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
> (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
> (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
> - return -1;
> - if (nread - (p - u.buf) <
> + goto bad;
> + if (nread - (p - u->buf) <
> sp->timecnt * stored + /* ats */
> sp->timecnt + /* types */
> sp->typecnt * 6 + /* ttinfos */
> @@ -412,7 +417,7 @@
> sp->leapcnt * (stored + 4) + /* lsinfos */
> ttisstdcnt + /* ttisstds */
> ttisgmtcnt) /* ttisgmts */
> - return -1;
> + goto bad;
> for (i = 0; i < sp->timecnt; ++i) {
> sp->ats[i] = (stored == 4) ?
> detzcode(p) : detzcode64(p);
> @@ -421,7 +426,7 @@
> for (i = 0; i < sp->timecnt; ++i) {
> sp->types[i] = (unsigned char) *p++;
> if (sp->types[i] >= sp->typecnt)
> - return -1;
> + goto bad;
> }
> for (i = 0; i < sp->typecnt; ++i) {
> register struct ttinfo * ttisp;
> @@ -431,11 +436,11 @@
> p += 4;
> ttisp->tt_isdst = (unsigned char) *p++;
> if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
> - return -1;
> + goto bad;
> ttisp->tt_abbrind = (unsigned char) *p++;
> if (ttisp->tt_abbrind < 0 ||
> ttisp->tt_abbrind > sp->charcnt)
> - return -1;
> + goto bad;
> }
> for (i = 0; i < sp->charcnt; ++i)
> sp->chars[i] = *p++;
> @@ -460,7 +465,7 @@
> ttisp->tt_ttisstd = *p++;
> if (ttisp->tt_ttisstd != TRUE &&
> ttisp->tt_ttisstd != FALSE)
> - return -1;
> + goto bad;
> }
> }
> for (i = 0; i < sp->typecnt; ++i) {
> @@ -473,7 +478,7 @@
> ttisp->tt_ttisgmt = *p++;
> if (ttisp->tt_ttisgmt != TRUE &&
> ttisp->tt_ttisgmt != FALSE)
> - return -1;
> + goto bad;
> }
> }
> /*
> @@ -506,11 +511,11 @@
> /*
> ** If this is an old file, we're done.
> */
> - if (u.tzhead.tzh_version[0] == '\0')
> + if (u->tzhead.tzh_version[0] == '\0')
> break;
> - nread -= p - u.buf;
> + nread -= p - u->buf;
> 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.
> */
> @@ -518,13 +523,13 @@
> break;
> }
> 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) {
> struct state ts;
> register int result;
>
> - u.buf[nread - 1] = '\0';
> - result = tzparse(&u.buf[1], &ts, FALSE);
> + 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)
> @@ -568,7 +573,11 @@
> break;
> }
> }
> + free(u);
> return 0;
> +bad:
> + free(u);
> + return -1;
> }
>
> static int
>
>
>
>
More information about the tz
mailing list