diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-25 10:39:32 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-25 10:39:32 -0300 |
| commit | b2d4d0642849319f90df48c067ba71c32d763523 (patch) | |
| tree | f8ef0ff328a76cc7d257dc81d1ac841db88a26cb | |
| parent | 3b8dba5279e98e03a194f048a82fcab9945bbbed (diff) | |
| download | lua-b2d4d0642849319f90df48c067ba71c32d763523.tar.gz lua-b2d4d0642849319f90df48c067ba71c32d763523.tar.bz2 lua-b2d4d0642849319f90df48c067ba71c32d763523.zip | |
avoid possible overflows when checking sizes in 'string.unpack'
| -rw-r--r-- | lstrlib.c | 19 |
1 files changed, 8 insertions, 11 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.261 2018/02/21 13:48:44 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.262 2018/02/21 17:48:31 roberto Exp roberto $ |
| 3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -1522,17 +1522,12 @@ static int str_packsize (lua_State *L) { | |||
| 1522 | while (*fmt != '\0') { | 1522 | while (*fmt != '\0') { |
| 1523 | int size, ntoalign; | 1523 | int size, ntoalign; |
| 1524 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); | 1524 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); |
| 1525 | luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, | ||
| 1526 | "variable-length format"); | ||
| 1525 | size += ntoalign; /* total space used by option */ | 1527 | size += ntoalign; /* total space used by option */ |
| 1526 | luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, | 1528 | luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, |
| 1527 | "format result too large"); | 1529 | "format result too large"); |
| 1528 | totalsize += size; | 1530 | totalsize += size; |
| 1529 | switch (opt) { | ||
| 1530 | case Kstring: /* strings with length count */ | ||
| 1531 | case Kzstr: /* zero-terminated string */ | ||
| 1532 | luaL_argerror(L, 1, "variable-length format"); | ||
| 1533 | /* call never return, but to avoid warnings: *//* FALLTHROUGH */ | ||
| 1534 | default: break; | ||
| 1535 | } | ||
| 1536 | } | 1531 | } |
| 1537 | lua_pushinteger(L, (lua_Integer)totalsize); | 1532 | lua_pushinteger(L, (lua_Integer)totalsize); |
| 1538 | return 1; | 1533 | return 1; |
| @@ -1585,8 +1580,8 @@ static int str_unpack (lua_State *L) { | |||
| 1585 | while (*fmt != '\0') { | 1580 | while (*fmt != '\0') { |
| 1586 | int size, ntoalign; | 1581 | int size, ntoalign; |
| 1587 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); | 1582 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); |
| 1588 | if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) | 1583 | luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, |
| 1589 | luaL_argerror(L, 2, "data string too short"); | 1584 | "data string too short"); |
| 1590 | pos += ntoalign; /* skip alignment */ | 1585 | pos += ntoalign; /* skip alignment */ |
| 1591 | /* stack space for item + next position */ | 1586 | /* stack space for item + next position */ |
| 1592 | luaL_checkstack(L, 2, "too many results"); | 1587 | luaL_checkstack(L, 2, "too many results"); |
| @@ -1615,13 +1610,15 @@ static int str_unpack (lua_State *L) { | |||
| 1615 | } | 1610 | } |
| 1616 | case Kstring: { | 1611 | case Kstring: { |
| 1617 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); | 1612 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); |
| 1618 | luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); | 1613 | luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); |
| 1619 | lua_pushlstring(L, data + pos + size, len); | 1614 | lua_pushlstring(L, data + pos + size, len); |
| 1620 | pos += len; /* skip string */ | 1615 | pos += len; /* skip string */ |
| 1621 | break; | 1616 | break; |
| 1622 | } | 1617 | } |
| 1623 | case Kzstr: { | 1618 | case Kzstr: { |
| 1624 | size_t len = (int)strlen(data + pos); | 1619 | size_t len = (int)strlen(data + pos); |
| 1620 | luaL_argcheck(L, pos + len < ld, 2, | ||
| 1621 | "unfinished string for format 'z'"); | ||
| 1625 | lua_pushlstring(L, data + pos, len); | 1622 | lua_pushlstring(L, data + pos, len); |
| 1626 | pos += len + 1; /* skip string plus final '\0' */ | 1623 | pos += len + 1; /* skip string plus final '\0' */ |
| 1627 | break; | 1624 | break; |
