mdbx: use saturated pgno_add() to avoid overflows.

Change-Id: I70000a86a69c9b3399d0a2c345d57ca1908f2881
This commit is contained in:
Leo Yuriev 2017-07-26 10:28:09 +03:00
parent a9927e7214
commit 4f06a38a50
2 changed files with 12 additions and 6 deletions

View File

@ -1195,3 +1195,8 @@ static __inline pgno_t bytes2pgno(const MDBX_env *env, size_t bytes) {
mdbx_assert(env, (env->me_psize >> env->me_psize2log) == 1);
return (pgno_t)(bytes >> env->me_psize2log);
}
static __inline pgno_t pgno_add(pgno_t base, pgno_t augend) {
assert(base <= MAX_PAGENO);
return (augend < MAX_PAGENO - base) ? base + augend : MAX_PAGENO;
}

View File

@ -1864,7 +1864,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
repg_pos = 0;
pgno = txn->mt_next_pgno;
rc = MDBX_MAP_FULL;
const pgno_t next = pgno + num;
const pgno_t next = pgno_add(pgno, num);
if (likely(next <= txn->mt_end_pgno)) {
rc = MDBX_NOTFOUND;
if (likely(flags & MDBX_ALLOC_NEW))
@ -1915,13 +1915,14 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
if (rc == MDBX_MAP_FULL && next < head->mm_geo.upper) {
mdbx_assert(env, next > txn->mt_end_pgno);
pgno_t growth_pgno = bytes2pgno(
env,
mdbx_roundup2(pgno2bytes(env, txn->mt_next_pgno + head->mm_geo.grow),
env->me_os_psize));
env, mdbx_roundup2(pgno2bytes(env, pgno_add(txn->mt_next_pgno,
head->mm_geo.grow)),
env->me_os_psize));
while (next >= growth_pgno)
growth_pgno = bytes2pgno(
env, mdbx_roundup2(pgno2bytes(env, growth_pgno + head->mm_geo.grow),
env->me_os_psize));
env, mdbx_roundup2(
pgno2bytes(env, pgno_add(growth_pgno, head->mm_geo.grow)),
env->me_os_psize));
if (growth_pgno > head->mm_geo.upper)
growth_pgno = head->mm_geo.upper;