]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Plug some information leaks
authorHoward Chu <hyc@openldap.org>
Fri, 30 Jun 2017 14:42:38 +0000 (15:42 +0100)
committerHoward Chu <hyc@openldap.org>
Sat, 10 Oct 2020 11:52:22 +0000 (12:52 +0100)
Zero out decrypted pages before freeing them.
Do proper init on reused loose pages.

libraries/liblmdb/mdb.c

index 6c7d8db4569b68a9f74c7b958127703e2123a1ac..c25f2d4f168a37167cbba576ad3555c619260d94 100644 (file)
@@ -1572,6 +1572,7 @@ static void mdb_txn_end(MDB_txn *txn, unsigned mode);
 #if MDB_RPAGE_CACHE
 static int  mdb_page_get(MDB_cursor *mc, pgno_t pgno, int numpgs, MDB_page **mp, int *lvl);
 #define MDB_PAGE_GET(mc, pg, numpgs, mp, lvl)  mdb_page_get(mc, pg, numpgs, mp, lvl)
+static void mdb_rpage_dispose(MDB_env *env, MDB_ID3 *id3);
 #else
 static int  mdb_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **mp, int *lvl);
 #define MDB_PAGE_GET(mc, pg, numpgs, mp, lvl)  mdb_page_get(mc, pg, mp, lvl)
@@ -1998,19 +1999,20 @@ mdb_page_malloc(MDB_txn *txn, unsigned num, int init)
         * many pages they will be filling in at least up to the last page.
         */
        if (num == 1) {
+               psize -= off = PAGEHDRSZ;
                if (ret) {
                        VGMEMP_ALLOC(env, ret, sz);
                        VGMEMP_DEFINED(ret, sizeof(ret->mp_next));
                        env->me_dpages = ret->mp_next;
-                       return ret;
+                       goto init;
                }
-               psize -= off = PAGEHDRSZ;
        } else {
                sz *= num;
                off = sz - psize;
        }
        if ((ret = malloc(sz)) != NULL) {
                VGMEMP_ALLOC(env, ret, sz);
+init:
                if (init && !(env->me_flags & MDB_NOMEMINIT)) {
                        memset((char *)ret + off, 0, psize);
                        ret->mp_pad = 0;
@@ -3393,7 +3395,7 @@ mdb_txn_end(MDB_txn *txn, unsigned mode)
                                /* tmp overflow pages that we didn't share in env */
                                munmap(tl[i].mptr, tl[i].mcnt * env->me_psize);
                                if (tl[i].menc) {
-                                       free(tl[i].menc);
+                                       mdb_rpage_dispose(env, &tl[i]);
                                        tl[i].menc = NULL;
                                }
                        } else {
@@ -3406,7 +3408,7 @@ mdb_txn_end(MDB_txn *txn, unsigned mode)
                                        /* another tmp overflow page */
                                        munmap(tl[i].mptr, tl[i].mcnt * env->me_psize);
                                        if (tl[i].menc) {
-                                               free(tl[i].menc);
+                                               mdb_rpage_dispose(env, &tl[i]);
                                                tl[i].menc = NULL;
                                        }
                                }
@@ -6130,7 +6132,7 @@ mdb_rpage_get(MDB_txn *txn, pgno_t pg0, int numpgs, MDB_page **ret)
                                tl[x].mptr = id3.mptr;
                                tl[x].mcnt = id3.mcnt;
                                if (tl[x].menc)
-                                       free(tl[x].menc);
+                                       mdb_rpage_dispose(env, &tl[x]);
                                tl[x].menc = id3.menc;
                                tl[x].muse = id3.muse;
                                /* if no active ref, see if we can replace in env */
@@ -6144,7 +6146,7 @@ mdb_rpage_get(MDB_txn *txn, pgno_t pg0, int numpgs, MDB_page **ret)
                                                el[i].mptr = tl[x].mptr;
                                                el[i].mcnt = tl[x].mcnt;
                                                if (el[i].menc)
-                                                       free(el[i].menc);
+                                                       mdb_rpage_dispose(env, &el[i]);
                                                el[i].menc = tl[x].menc;
                                                el[i].muse = tl[x].muse;
                                        } else {
@@ -6181,7 +6183,7 @@ retry:
                                if (tl[i].mid & (MDB_RPAGE_CHUNK-1)) {
                                        munmap(tl[i].mptr, tl[i].mcnt * env->me_psize);
                                        if (tl[i].menc)
-                                               free(tl[i].menc);
+                                               mdb_rpage_dispose(env, &tl[i]);
                                        continue;
                                }
                                x = mdb_mid3l_search(el, tl[i].mid);
@@ -6250,7 +6252,7 @@ retry:
                                        el[x].mptr = id3.mptr;
                                        el[x].mcnt = id3.mcnt;
                                        if (el[x].menc)
-                                               free(el[x].menc);
+                                               mdb_rpage_dispose(env, &el[x]);
                                        el[x].menc = id3.menc;
                                        el[x].muse = id3.muse;
                                } else {
@@ -6279,7 +6281,7 @@ retry:
                                        if (!y) y = i;
                                        munmap(el[i].mptr, env->me_psize * el[i].mcnt);
                                        if (el[i].menc)
-                                               free(el[i].menc);
+                                               mdb_rpage_dispose(env, &el[i]);
                                }
                        }
                        if (!y) {
@@ -6345,7 +6347,15 @@ static void mdb_rpage_decrypt(MDB_env *env, MDB_ID3 *id3, int rem, int numpgs)
 {
        if (!(id3->muse & (1 << rem))) {
                MDB_val in, out;
-               id3->muse |= (1 << rem);
+               int bit;
+
+               /* If this is an overflow page, set all use bits to the end */
+               if (rem + numpgs > MDB_RPAGE_CHUNK)
+                       bit = 0xffff;
+               else
+                       bit = 1;
+
+               id3->muse |= (bit << rem);
                in.mv_size = numpgs * env->me_psize;
                in.mv_data = (char *)id3->mptr + rem * env->me_psize;
                out.mv_size = in.mv_size;
@@ -6353,6 +6363,24 @@ static void mdb_rpage_decrypt(MDB_env *env, MDB_ID3 *id3, int rem, int numpgs)
                env->me_encfunc(&in, &out, env->me_enckey, 0);
        }
 }
+
+/** zero out decrypted pages before freeing them */
+static void mdb_rpage_dispose(MDB_env *env, MDB_ID3 *id3)
+{
+       char *base = id3->menc;
+       int i, j;
+       for (i=0, j=1; i<15; i++) {
+               if (id3->muse & j)
+                       memset(base, 0, env->me_psize);
+               j <<= 1;
+               base += env->me_psize;
+       }
+       if (id3->muse & j) {
+               i = id3->mcnt - (MDB_RPAGE_CHUNK - 1);
+               memset(base, 0, i * env->me_psize);
+       }
+       free(id3->menc);
+}
 #endif
 
 /** Find the address of the page corresponding to a given page number.