Fix CVE-2019-2708
This commit is contained in:
parent
3247646677
commit
cb92baa0a3
@ -0,0 +1,704 @@
|
||||
From 6e31ff213f630b146882a0cb832a25cc2dcaaed8 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||
Date: Wed, 2 Dec 2020 15:50:09 +0100
|
||||
Subject: [PATCH] Resolved data store execution which led to partial DoS
|
||||
|
||||
Resolves: #1853243
|
||||
|
||||
--- db-18.1.32/src/btree/bt_cursor.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/btree/bt_cursor.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -282,6 +282,8 @@
|
||||
*
|
||||
* Recno uses the btree bt_ovflsize value -- it's close enough.
|
||||
*/
|
||||
+ if (t->bt_minkey == 0)
|
||||
+ return (DB_RECOVER);
|
||||
cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
|
||||
dbp, F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
|
||||
|
||||
--- db-18.1.32/src/btree/bt_verify.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/btree/bt_verify.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -611,7 +611,11 @@
|
||||
isbad = 1;
|
||||
goto err;
|
||||
default:
|
||||
+ if (ret == 0) {
|
||||
+ isbad = 1;
|
||||
+ ret = DB_VERIFY_FATAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
- DB_ASSERT(env, ret != 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -922,7 +926,7 @@
|
||||
DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;
|
||||
ENV *env;
|
||||
PAGE *child;
|
||||
+ db_pgno_t cpgno, grandparent;
|
||||
- db_pgno_t cpgno;
|
||||
VRFY_PAGEINFO *pip;
|
||||
db_indx_t i, *inp;
|
||||
int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret;
|
||||
@@ -954,7 +958,8 @@
|
||||
|
||||
buf1 = buf2 = NULL;
|
||||
|
||||
+ if (LF_ISSET(DB_NOORDERCHK))
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK));
|
||||
|
||||
dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
|
||||
if (TYPE(h) == P_LDUP)
|
||||
@@ -963,6 +968,7 @@
|
||||
func = __bam_defcmp;
|
||||
if (dbp->bt_internal != NULL) {
|
||||
bt = (BTREE *)dbp->bt_internal;
|
||||
+ grandparent = bt->bt_root;
|
||||
if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL ||
|
||||
dupfunc != __bam_defcmp)) {
|
||||
/*
|
||||
@@ -974,8 +980,24 @@
|
||||
*/
|
||||
mpf = dbp->mpf;
|
||||
child = h;
|
||||
+ cpgno = pgno;
|
||||
while (TYPE(child) == P_IBTREE) {
|
||||
+ if (NUM_ENT(child) == 0) {
|
||||
+ EPRINT((env, DB_STR_A("1088",
|
||||
+ "Page %lu: internal page is empty and should not be",
|
||||
+ "%lu"), (u_long)cpgno));
|
||||
+ ret = DB_VERIFY_BAD;
|
||||
+ goto err;
|
||||
+ }
|
||||
bi = GET_BINTERNAL(dbp, child, 0);
|
||||
+ if (grandparent == bi->pgno) {
|
||||
+ EPRINT((env, DB_STR_A("5552",
|
||||
+ "Page %lu: found twice in the btree",
|
||||
+ "%lu"), (u_long)grandparent));
|
||||
+ ret = DB_VERIFY_FATAL;
|
||||
+ goto err;
|
||||
+ } else
|
||||
+ grandparent = cpgno;
|
||||
cpgno = bi->pgno;
|
||||
if (child != h &&
|
||||
(ret = __memp_fput(mpf,
|
||||
@@ -1231,7 +1253,10 @@
|
||||
*/
|
||||
if (dup_1.data == NULL ||
|
||||
dup_2.data == NULL) {
|
||||
+ if (ovflok) {
|
||||
+ isbad = 1;
|
||||
+ goto err;
|
||||
+ }
|
||||
- DB_ASSERT(env, !ovflok);
|
||||
if (pip != NULL)
|
||||
F_SET(pip,
|
||||
VRFY_INCOMPLETE);
|
||||
@@ -1569,9 +1594,10 @@
|
||||
(ret = __db_vrfy_ovfl_structure(dbp, vdp,
|
||||
child->pgno, child->tlen,
|
||||
flags | DB_ST_OVFL_LEAF)) != 0) {
|
||||
+ if (ret == DB_VERIFY_BAD) {
|
||||
- if (ret == DB_VERIFY_BAD)
|
||||
isbad = 1;
|
||||
+ break;
|
||||
+ } else
|
||||
- else
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1645,9 +1671,10 @@
|
||||
stflags | DB_ST_TOPLEVEL,
|
||||
NULL, NULL, NULL)) != 0) {
|
||||
if (ret ==
|
||||
+ DB_VERIFY_BAD) {
|
||||
- DB_VERIFY_BAD)
|
||||
isbad = 1;
|
||||
+ break;
|
||||
+ } else
|
||||
- else
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -1790,7 +1817,10 @@
|
||||
*/
|
||||
|
||||
/* Otherwise, __db_vrfy_childput would be broken. */
|
||||
+ if (child->refcnt < 1) {
|
||||
+ isbad = 1;
|
||||
+ goto err;
|
||||
+ }
|
||||
- DB_ASSERT(env, child->refcnt >= 1);
|
||||
|
||||
/*
|
||||
* An overflow referenced more than twice here
|
||||
@@ -1807,9 +1837,10 @@
|
||||
if ((ret = __db_vrfy_ovfl_structure(dbp,
|
||||
vdp, child->pgno, child->tlen,
|
||||
flags)) != 0) {
|
||||
+ if (ret == DB_VERIFY_BAD) {
|
||||
- if (ret == DB_VERIFY_BAD)
|
||||
isbad = 1;
|
||||
+ break;
|
||||
+ } else
|
||||
- else
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -1847,9 +1878,10 @@
|
||||
if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
|
||||
i == 0 ? NULL : li, ri, flags, &child_level,
|
||||
&child_nrecs, NULL)) != 0) {
|
||||
+ if (ret == DB_VERIFY_BAD) {
|
||||
- if (ret == DB_VERIFY_BAD)
|
||||
isbad = 1;
|
||||
+ break;
|
||||
+ } else
|
||||
- else
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2675,7 +2707,11 @@
|
||||
db_pgno_t current, p;
|
||||
int err_ret, ret;
|
||||
|
||||
+ if (pgset == NULL) {
|
||||
+ EPRINT((dbp->env, DB_STR("5542",
|
||||
+ "Error, database contains no visible pages.")));
|
||||
+ return (DB_RUNRECOVERY);
|
||||
+ }
|
||||
- DB_ASSERT(dbp->env, pgset != NULL);
|
||||
|
||||
mpf = dbp->mpf;
|
||||
h = NULL;
|
||||
--- db-18.1.32/src/db/db_conv.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/db/db_conv.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -493,8 +493,11 @@
|
||||
db_indx_t i, *inp, len, tmp;
|
||||
u_int8_t *end, *p, *pgend;
|
||||
|
||||
- if (pagesize == 0)
|
||||
- return (0);
|
||||
+ /* This function is also used to byteswap logs, so
|
||||
+ * the pagesize might not be an actual page size.
|
||||
+ */
|
||||
+ if (!(pagesize >= 24 && pagesize <= DB_MAX_PGSIZE))
|
||||
+ return (EINVAL);
|
||||
|
||||
if (pgin) {
|
||||
M_32_SWAP(h->lsn.file);
|
||||
@@ -513,26 +516,41 @@
|
||||
pgend = (u_int8_t *)h + pagesize;
|
||||
|
||||
inp = P_INP(dbp, h);
|
||||
- if ((u_int8_t *)inp >= pgend)
|
||||
- goto out;
|
||||
+ if ((u_int8_t *)inp > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
switch (TYPE(h)) {
|
||||
case P_HASH_UNSORTED:
|
||||
case P_HASH:
|
||||
for (i = 0; i < NUM_ENT(h); i++) {
|
||||
+ if ((u_int8_t*)(inp + i) >= pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
+ if (inp[i] == 0)
|
||||
+ continue;
|
||||
if (pgin)
|
||||
M_16_SWAP(inp[i]);
|
||||
+ if (inp[i] >= pagesize)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
- if (P_ENTRY(dbp, h, i) >= pgend)
|
||||
- continue;
|
||||
+ if (P_ENTRY(dbp, h, i) >= pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
switch (HPAGE_TYPE(dbp, h, i)) {
|
||||
case H_KEYDATA:
|
||||
break;
|
||||
case H_DUPLICATE:
|
||||
+ if (LEN_HITEM(dbp, h, pagesize, i) <
|
||||
+ HKEYDATA_SIZE(0))
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
+
|
||||
len = LEN_HKEYDATA(dbp, h, pagesize, i);
|
||||
p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
|
||||
- for (end = p + len; p < end;) {
|
||||
+
|
||||
+ end = p + len;
|
||||
+ if (end > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
+
|
||||
+ while (p < end) {
|
||||
if (pgin) {
|
||||
P_16_SWAP(p);
|
||||
memcpy(&tmp,
|
||||
@@ -544,14 +562,20 @@
|
||||
SWAP16(p);
|
||||
}
|
||||
p += tmp;
|
||||
+ if (p >= end)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
SWAP16(p);
|
||||
}
|
||||
break;
|
||||
case H_OFFDUP:
|
||||
+ if ((inp[i] + HOFFDUP_SIZE) > pagesize)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
|
||||
SWAP32(p); /* pgno */
|
||||
break;
|
||||
case H_OFFPAGE:
|
||||
+ if ((inp[i] + HOFFPAGE_SIZE) > pagesize)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
|
||||
SWAP32(p); /* pgno */
|
||||
SWAP32(p); /* tlen */
|
||||
@@ -559,7 +583,6 @@
|
||||
default:
|
||||
return (__db_pgfmt(env, pg));
|
||||
}
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -576,8 +599,12 @@
|
||||
case P_LDUP:
|
||||
case P_LRECNO:
|
||||
for (i = 0; i < NUM_ENT(h); i++) {
|
||||
+ if ((u_int8_t *)(inp + i) >= pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
if (pgin)
|
||||
M_16_SWAP(inp[i]);
|
||||
+ if (inp[i] >= pagesize)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
/*
|
||||
* In the case of on-page duplicates, key information
|
||||
@@ -597,7 +624,7 @@
|
||||
|
||||
bk = GET_BKEYDATA(dbp, h, i);
|
||||
if ((u_int8_t *)bk >= pgend)
|
||||
- continue;
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
switch (B_TYPE(bk->type)) {
|
||||
case B_KEYDATA:
|
||||
M_16_SWAP(bk->len);
|
||||
@@ -605,6 +632,8 @@
|
||||
case B_DUPLICATE:
|
||||
case B_OVERFLOW:
|
||||
bo = (BOVERFLOW *)bk;
|
||||
+ if (((u_int8_t *)bo + BOVERFLOW_SIZE) > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
M_32_SWAP(bo->pgno);
|
||||
M_32_SWAP(bo->tlen);
|
||||
break;
|
||||
@@ -618,12 +647,17 @@
|
||||
break;
|
||||
case P_IBTREE:
|
||||
for (i = 0; i < NUM_ENT(h); i++) {
|
||||
+ if ((u_int8_t *)(inp + i) > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
if (pgin)
|
||||
M_16_SWAP(inp[i]);
|
||||
+ if ((u_int16_t)(inp[i] +
|
||||
+ BINTERNAL_SIZE(0) - 1) > pagesize)
|
||||
+ break;
|
||||
|
||||
bi = GET_BINTERNAL(dbp, h, i);
|
||||
- if ((u_int8_t *)bi >= pgend)
|
||||
- continue;
|
||||
+ if (((u_int8_t *)bi + BINTERNAL_SIZE(0)) > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
M_16_SWAP(bi->len);
|
||||
M_32_SWAP(bi->pgno);
|
||||
@@ -634,6 +668,10 @@
|
||||
break;
|
||||
case B_DUPLICATE:
|
||||
case B_OVERFLOW:
|
||||
+ if ((u_int16_t)(inp[i] +
|
||||
+ BINTERNAL_SIZE(BOVERFLOW_SIZE) - 1) >
|
||||
+ pagesize)
|
||||
+ goto out;
|
||||
bo = (BOVERFLOW *)bi->data;
|
||||
M_32_SWAP(bo->pgno);
|
||||
M_32_SWAP(bo->tlen);
|
||||
@@ -648,12 +686,16 @@
|
||||
break;
|
||||
case P_IRECNO:
|
||||
for (i = 0; i < NUM_ENT(h); i++) {
|
||||
+ if ((u_int8_t *)(inp + i) >= pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
if (pgin)
|
||||
M_16_SWAP(inp[i]);
|
||||
+ if (inp[i] >= pagesize)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
ri = GET_RINTERNAL(dbp, h, i);
|
||||
- if ((u_int8_t *)ri >= pgend)
|
||||
- continue;
|
||||
+ if ((((u_int8_t *)ri) + RINTERNAL_SIZE) > pgend)
|
||||
+ return (__db_pgfmt(env, pg));
|
||||
|
||||
M_32_SWAP(ri->pgno);
|
||||
M_32_SWAP(ri->nrecs);
|
||||
--- db-18.1.32/src/db/db_vrfy.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/db/db_vrfy.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -375,8 +375,10 @@
|
||||
vdp, name, 0, lp, rp, flags)) != 0) {
|
||||
if (t_ret == DB_VERIFY_BAD)
|
||||
isbad = 1;
|
||||
+ else {
|
||||
+ ret = t_ret;
|
||||
+ goto err;
|
||||
+ }
|
||||
- else
|
||||
- goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -764,9 +766,10 @@
|
||||
*/
|
||||
if ((t_ret = __memp_fget(mpf, &i,
|
||||
vdp->thread_info, NULL, 0, &h)) != 0) {
|
||||
+ if ((dbp->type == DB_HASH ||
|
||||
- if (dbp->type == DB_HASH ||
|
||||
(dbp->type == DB_QUEUE &&
|
||||
+ F_ISSET(dbp, DB_AM_INMEM))) &&
|
||||
+ t_ret != DB_RUNRECOVERY) {
|
||||
- F_ISSET(dbp, DB_AM_INMEM))) {
|
||||
if ((t_ret =
|
||||
__db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
|
||||
goto err1;
|
||||
@@ -936,6 +939,8 @@
|
||||
return (ret == 0 ? t_ret : ret);
|
||||
}
|
||||
|
||||
+ if (ret == DB_PAGE_NOTFOUND && isbad == 1)
|
||||
+ ret = 0;
|
||||
return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
|
||||
}
|
||||
|
||||
@@ -1567,7 +1572,7 @@
|
||||
if (pgno == PGNO_BASE_MD &&
|
||||
dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) {
|
||||
#ifdef HAVE_FTRUNCATE
|
||||
+ ret = DB_VERIFY_FATAL;
|
||||
- isbad = 1;
|
||||
EPRINT((env, DB_STR_A("0552",
|
||||
"Page %lu: last_pgno is not correct: %lu != %lu",
|
||||
"%lu %lu %lu"), (u_long)pgno,
|
||||
@@ -1608,7 +1613,11 @@
|
||||
|
||||
env = dbp->env;
|
||||
pgset = vdp->pgset;
|
||||
+ if (pgset == NULL) {
|
||||
+ EPRINT((env, DB_STR("5543",
|
||||
+ "Error, database contains no visible pages.")));
|
||||
+ return (DB_RUNRECOVERY);
|
||||
+ }
|
||||
- DB_ASSERT(env, pgset != NULL);
|
||||
|
||||
if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
|
||||
return (ret);
|
||||
@@ -1993,7 +2002,8 @@
|
||||
int keyflag, ret, t_ret;
|
||||
|
||||
env = dbp->env;
|
||||
+ if (!LF_ISSET(DB_SALVAGE))
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
|
||||
|
||||
/*
|
||||
* !!!
|
||||
@@ -2126,10 +2136,8 @@
|
||||
int (*callback) __P((void *, const void *));
|
||||
u_int32_t flags;
|
||||
{
|
||||
- ENV *env;
|
||||
-
|
||||
- env = dbp->env;
|
||||
- DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
|
||||
+ if (!LF_ISSET(DB_SALVAGE))
|
||||
+ return (EINVAL);
|
||||
|
||||
/* If we got this page in the subdb pass, we can safely skip it. */
|
||||
if (__db_salvage_isdone(vdp, pgno))
|
||||
@@ -2223,8 +2231,8 @@
|
||||
ret = t_ret;
|
||||
break;
|
||||
case SALVAGE_OVERFLOW:
|
||||
+ EPRINT((env, DB_STR("5544", "Invalid page type to salvage.")));
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(env, 0); /* Shouldn't ever happen. */
|
||||
- break;
|
||||
case SALVAGE_HASH:
|
||||
if ((t_ret = __ham_salvage(dbp, vdp,
|
||||
pgno, h, handle, callback, flags)) != 0 && ret == 0)
|
||||
@@ -2237,8 +2245,8 @@
|
||||
* Shouldn't happen, but if it does, just do what the
|
||||
* nice man says.
|
||||
*/
|
||||
+ EPRINT((env, DB_STR("5545", "Invalid page type to salvage.")));
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(env, 0);
|
||||
- break;
|
||||
}
|
||||
if ((t_ret = __memp_fput(mpf,
|
||||
vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
|
||||
@@ -2284,8 +2292,8 @@
|
||||
ret = t_ret;
|
||||
break;
|
||||
default:
|
||||
+ EPRINT((env, DB_STR("5546", "Invalid page type to salvage.")));
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(env, 0); /* Shouldn't ever happen. */
|
||||
- break;
|
||||
}
|
||||
if ((t_ret = __memp_fput(mpf,
|
||||
vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
|
||||
@@ -2342,7 +2350,10 @@
|
||||
|
||||
env = dbp->env;
|
||||
|
||||
+ if (himarkp == NULL) {
|
||||
+ __db_msg(env, "Page %lu index has no end.", (u_long)pgno);
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
+ }
|
||||
- DB_ASSERT(env, himarkp != NULL);
|
||||
inp = P_INP(dbp, h);
|
||||
|
||||
/*
|
||||
@@ -2755,7 +2766,11 @@
|
||||
goto err;
|
||||
ovfl_bufsz = bkkey->len + 1;
|
||||
}
|
||||
+ if (subdbname == NULL) {
|
||||
+ EPRINT((env, DB_STR("5547", "Subdatabase cannot be null.")));
|
||||
+ ret = EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
- DB_ASSERT(env, subdbname != NULL);
|
||||
memcpy(subdbname, bkkey->data, bkkey->len);
|
||||
subdbname[bkkey->len] = '\0';
|
||||
}
|
||||
--- db-18.1.32/src/db/db_vrfyutil.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/db/db_vrfyutil.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -208,7 +208,8 @@
|
||||
if ((ret = __db_get(pgdbp,
|
||||
vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
|
||||
/* Found it. */
|
||||
+ if (data.size != sizeof(VRFY_PAGEINFO))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO));
|
||||
pip = data.data;
|
||||
LIST_INSERT_HEAD(&vdp->activepips, pip, links);
|
||||
goto found;
|
||||
@@ -336,7 +337,8 @@
|
||||
F_SET(&data, DB_DBT_USERMEM);
|
||||
|
||||
if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
|
||||
+ if (data.size != sizeof(int))
|
||||
+ return (EINVAL);
|
||||
- DB_ASSERT(dbp->env, data.size == sizeof(int));
|
||||
} else if (ret == DB_NOTFOUND)
|
||||
val = 0;
|
||||
else
|
||||
@@ -376,7 +378,8 @@
|
||||
F_SET(&data, DB_DBT_USERMEM);
|
||||
|
||||
if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
|
||||
+ if (data.size != sizeof(int))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbp->env, data.size == sizeof(int));
|
||||
} else if (ret != DB_NOTFOUND)
|
||||
return (ret);
|
||||
|
||||
@@ -413,7 +416,8 @@
|
||||
if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0)
|
||||
return (ret);
|
||||
|
||||
+ if (key.size != sizeof(db_pgno_t))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t));
|
||||
*pgnop = pgno;
|
||||
|
||||
return (0);
|
||||
@@ -560,7 +564,8 @@
|
||||
if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0)
|
||||
return (ret);
|
||||
|
||||
+ if (data.size != sizeof(VRFY_CHILDINFO))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
|
||||
*cipp = (VRFY_CHILDINFO *)data.data;
|
||||
|
||||
return (0);
|
||||
@@ -588,7 +593,8 @@
|
||||
if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
|
||||
return (ret);
|
||||
|
||||
+ if (data.size != sizeof(VRFY_CHILDINFO))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
|
||||
*cipp = (VRFY_CHILDINFO *)data.data;
|
||||
|
||||
return (0);
|
||||
@@ -715,7 +721,8 @@
|
||||
return (ret);
|
||||
|
||||
while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
|
||||
+ if (data.size != sizeof(u_int32_t))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
|
||||
memcpy(&pgtype, data.data, sizeof(pgtype));
|
||||
|
||||
if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
|
||||
@@ -724,8 +731,9 @@
|
||||
if ((ret = __dbc_del(*dbcp, 0)) != 0)
|
||||
return (ret);
|
||||
if (pgtype != SALVAGE_IGNORE) {
|
||||
+ if (key.size != sizeof(db_pgno_t)
|
||||
+ || data.size != sizeof(u_int32_t))
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
- DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t));
|
||||
- DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
|
||||
|
||||
*pgnop = *(db_pgno_t *)key.data;
|
||||
*pgtypep = *(u_int32_t *)data.data;
|
||||
--- db-18.1.32/src/db/partition.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/db/partition.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -461,9 +461,19 @@
|
||||
} else
|
||||
part->nparts = meta->nparts;
|
||||
} else if (meta->nparts != 0 && part->nparts != meta->nparts) {
|
||||
+ ret = EINVAL;
|
||||
__db_errx(env, DB_STR("0656",
|
||||
"Number of partitions does not match."));
|
||||
- ret = EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ /*
|
||||
+ * There is no limit on the number of partitions, but I cannot imagine a real
|
||||
+ * database having more than 10000.
|
||||
+ */
|
||||
+ if (meta->nparts > 10000) {
|
||||
+ ret = EINVAL;
|
||||
+ __db_errx(env, DB_STR_A("5553",
|
||||
+ "Too many partitions %lu", "%lu"), (u_long)(meta->nparts));
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -1874,10 +1884,13 @@
|
||||
memcpy(rp->data, key->data, key->size);
|
||||
B_TSET(rp->type, B_KEYDATA);
|
||||
}
|
||||
+vrfy: if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
|
||||
+ NULL, handle, callback,
|
||||
+ lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0) {
|
||||
+ ret = t_ret;
|
||||
+ if (ret == ENOENT)
|
||||
+ break;
|
||||
+ }
|
||||
-vrfy: if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
|
||||
- NULL, handle, callback,
|
||||
- lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0)
|
||||
- ret = t_ret;
|
||||
}
|
||||
|
||||
err: if (lp != NULL)
|
||||
--- db-18.1.32/src/hash/hash_page.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/hash/hash_page.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -865,7 +865,11 @@
|
||||
/* Validate that next, prev pointers are OK */
|
||||
n = NUM_ENT(p);
|
||||
dbp = dbc->dbp;
|
||||
+ if (n % 2 != 0) {
|
||||
+ __db_errx(dbp->env, DB_STR_A("5549",
|
||||
+ "Odd number of entries on page: %lu", "%lu"), (u_long)(p->pgno));
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
+ }
|
||||
- DB_ASSERT(dbp->env, n%2 == 0 );
|
||||
|
||||
env = dbp->env;
|
||||
t = dbp->h_internal;
|
||||
@@ -936,7 +940,12 @@
|
||||
if ((ret = __db_prpage(dbp, p, DB_PR_PAGE)) != 0)
|
||||
return (ret);
|
||||
#endif
|
||||
+ if (res >= 0) {
|
||||
+ __db_errx(env, DB_STR_A("5550",
|
||||
+ "Odd number of entries on page: %lu", "%lu"),
|
||||
+ (u_long)p->pgno);
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
+ }
|
||||
- DB_ASSERT(dbp->env, res < 0);
|
||||
}
|
||||
|
||||
prev = curr;
|
||||
--- db-18.1.32/src/hash/hash_verify.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/hash/hash_verify.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -443,7 +443,7 @@
|
||||
isbad = 1;
|
||||
else
|
||||
goto err;
|
||||
+ }
|
||||
- }
|
||||
|
||||
/*
|
||||
* There may be unused hash pages corresponding to buckets
|
||||
@@ -574,7 +574,7 @@
|
||||
"Page %lu: impossible first page in bucket %lu", "%lu %lu"),
|
||||
(u_long)pgno, (u_long)bucket));
|
||||
/* Unsafe to continue. */
|
||||
+ ret = DB_VERIFY_FATAL;
|
||||
- isbad = 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
EPRINT((env, DB_STR_A("1116",
|
||||
"Page %lu: hash page referenced twice", "%lu"),
|
||||
(u_long)pgno));
|
||||
+ ret = DB_VERIFY_FATAL;
|
||||
- isbad = 1;
|
||||
/* Unsafe to continue. */
|
||||
goto err;
|
||||
} else if ((ret = __db_vrfy_pgset_inc(vdp->pgset,
|
||||
@@ -1049,7 +1049,11 @@
|
||||
COMPQUIET(flags, 0);
|
||||
ip = vdp->thread_info;
|
||||
|
||||
+ if (pgset == NULL) {
|
||||
+ EPRINT((dbp->env, DB_STR("5548",
|
||||
+ "Error, database contains no visible pages.")));
|
||||
+ return (DB_VERIFY_FATAL);
|
||||
+ }
|
||||
- DB_ASSERT(dbp->env, pgset != NULL);
|
||||
|
||||
mpf = dbp->mpf;
|
||||
totpgs = 0;
|
||||
--- db-18.1.32/src/qam/qam_verify.c 2019-02-20 03:21:20.000000000 +0530
|
||||
+++ db-18.1.40/src/qam/qam_verify.c 2020-05-29 23:28:22.000000000 +0530
|
||||
@@ -465,7 +465,14 @@
|
||||
/* Verify/salvage each page. */
|
||||
if ((ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0)
|
||||
return (ret);
|
||||
-begin: for (; i <= stop; i++) {
|
||||
+begin: if ((stop - i) > 100000) {
|
||||
+ EPRINT((env, DB_STR_A("5551",
|
||||
+"Warning, many possible extends files (%lu), will take a long time to verify",
|
||||
+ "%lu"), (u_long)(stop - i)));
|
||||
+ }
|
||||
+ for (; i <= stop; i++) {
|
||||
+ if (i == UINT32_MAX)
|
||||
+ break;
|
||||
/*
|
||||
* If DB_SALVAGE is set, we inspect our database of completed
|
||||
* pages, and skip any we've already printed in the subdb pass.
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: libdb
|
||||
Version: 5.3.28
|
||||
Release: 36
|
||||
Release: 37
|
||||
Summary: The Berkeley DB database library for C
|
||||
License: BSD and LGPLv2 and Sleepycat
|
||||
URL: https://www.oracle.com/database/berkeley-db/
|
||||
@ -32,6 +32,7 @@ Patch34: libdb-5.3.21-region-size-check.patch
|
||||
# Patch sent upstream
|
||||
Patch35: checkpoint-opd-deadlock.patch
|
||||
Patch36: db-5.3.28-atomic_compare_exchange.patch
|
||||
Patch37: backport-CVE-2019-2708-Resolved-data-store-execution-which-led-to-partial-DoS.patch
|
||||
|
||||
Patch9000: bugfix-fix-deadlock-on-mempool-file-locks.patch
|
||||
|
||||
@ -112,6 +113,7 @@ popd
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
|
||||
%patch9000 -p1
|
||||
|
||||
@ -209,6 +211,9 @@ mv man/* %{buildroot}%{_mandir}/man1/
|
||||
%{_mandir}/man1
|
||||
|
||||
%changelog
|
||||
* Mon Apr 19 2021 wangchen <wangchen137@huawei.com> - 5.3.28-37
|
||||
- Fix CVE-2019-2708
|
||||
|
||||
* Tue Sep 8 2020 wangchen <wangchen137@huawei.com> - 5.3.28-36
|
||||
- Modify the URL of Source0
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user