Control: tags -1 +patch
Hello!
Upstream has provided a patch now [1] which fixes the issue for me.
It applies against both OpenLDAP 2.5.13 and 2.6.3 with fuzz and by fixing
a single printf() statement manually. I am attaching the backported patch
which applies cleanly.
Thanks,
Adrian
[1] https://git.openldap.org/openldap/openldap/-/merge_requests/582
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`-GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
--- openldap-2.5.13+dfsg.orig/libraries/liblmdb/mdb.c
+++ openldap-2.5.13+dfsg/libraries/liblmdb/mdb.c
@@ -823,8 +823,6 @@ typedef struct MDB_page {
#define P_KEEP 0x8000 /**< leave this page alone during spill */
/** @} */
uint16_t mp_flags; /**< @ref mdb_page */
-#define mp_lower mp_pb.pb.pb_lower
-#define mp_upper mp_pb.pb.pb_upper
#define mp_pages mp_pb.pb_pages
union {
struct {
@@ -833,9 +831,26 @@ typedef struct MDB_page {
} pb;
uint32_t pb_pages; /**< number of overflow pages */
} mp_pb;
- indx_t mp_ptrs[1]; /**< dynamic size */
+ indx_t mp_ptrs[0]; /**< dynamic size */
} MDB_page;
+/** Alternate page header, for 2-byte aligned access */
+typedef struct MDB_page2 {
+ uint16_t mp_p[sizeof(pgno_t)/2];
+ uint16_t mp_pad;
+ uint16_t mp_flags;
+ indx_t mp_lower;
+ indx_t mp_upper;
+ indx_t mp_ptrs[0];
+} MDB_page2;
+
+#define MP_PGNO(p) (((MDB_page2 *)(void *)(p))->mp_p)
+#define MP_PAD(p) (((MDB_page2 *)(void *)(p))->mp_pad)
+#define MP_FLAGS(p) (((MDB_page2 *)(void *)(p))->mp_flags)
+#define MP_LOWER(p) (((MDB_page2 *)(void *)(p))->mp_lower)
+#define MP_UPPER(p) (((MDB_page2 *)(void *)(p))->mp_upper)
+#define MP_PTRS(p) (((MDB_page2 *)(void *)(p))->mp_ptrs)
+
/** Size of the page header, excluding dynamic data at the end */
#define PAGEHDRSZ ((unsigned) offsetof(MDB_page, mp_ptrs))
@@ -846,10 +861,10 @@ typedef struct MDB_page {
#define PAGEBASE ((MDB_DEVEL) ? PAGEHDRSZ : 0)
/** Number of nodes on a page */
-#define NUMKEYS(p) (((p)->mp_lower - (PAGEHDRSZ-PAGEBASE)) >> 1)
+#define NUMKEYS(p) ((MP_LOWER(p) - (PAGEHDRSZ-PAGEBASE)) >> 1)
/** The amount of space remaining in the page */
-#define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower)
+#define SIZELEFT(p) (indx_t)(MP_UPPER(p) - MP_LOWER(p))
/** The percentage of space used in the page, in tenths of a percent. */
#define PAGEFILL(env, p) (1000L * ((env)->me_psize - PAGEHDRSZ - SIZELEFT(p)) / \
@@ -860,15 +875,15 @@ typedef struct MDB_page {
#define FILL_THRESHOLD 250
/** Test if a page is a leaf page */
-#define IS_LEAF(p) F_ISSET((p)->mp_flags, P_LEAF)
+#define IS_LEAF(p) F_ISSET(MP_FLAGS(p), P_LEAF)
/** Test if a page is a LEAF2 page */
-#define IS_LEAF2(p) F_ISSET((p)->mp_flags, P_LEAF2)
+#define IS_LEAF2(p) F_ISSET(MP_FLAGS(p), P_LEAF2)
/** Test if a page is a branch page */
-#define IS_BRANCH(p) F_ISSET((p)->mp_flags, P_BRANCH)
+#define IS_BRANCH(p) F_ISSET(MP_FLAGS(p), P_BRANCH)
/** Test if a page is an overflow page */
-#define IS_OVERFLOW(p) F_ISSET((p)->mp_flags, P_OVERFLOW)
+#define IS_OVERFLOW(p) F_ISSET(MP_FLAGS(p), P_OVERFLOW)
/** Test if a page is a sub page */
-#define IS_SUBP(p) F_ISSET((p)->mp_flags, P_SUBP)
+#define IS_SUBP(p) F_ISSET(MP_FLAGS(p), P_SUBP)
/** The number of overflow pages needed to store the given size. */
#define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1)
@@ -936,7 +951,7 @@ typedef struct MDB_node {
#define LEAFSIZE(k, d) (NODESIZE + (k)->mv_size + (d)->mv_size)
/** Address of node \b i in page \b p */
-#define NODEPTR(p, i) ((MDB_node *)((char *)(p) + (p)->mp_ptrs[i] + PAGEBASE))
+#define NODEPTR(p, i) ((MDB_node *)((char *)(p) + MP_PTRS(p)[i] + PAGEBASE))
/** Address of the key for the node */
#define NODEKEY(node) (void *)((node)->mn_data)
@@ -964,6 +979,8 @@ typedef struct MDB_node {
/** Copy a page number from src to dst */
#ifdef MISALIGNED_OK
#define COPY_PGNO(dst,src) dst = src
+#undef MP_PGNO
+#define MP_PGNO(p) ((p)->mp_pgno)
#else
#if SIZE_MAX > 4294967295UL
#define COPY_PGNO(dst,src) do { \
@@ -1554,7 +1571,7 @@ static pgno_t
mdb_dbg_pgno(MDB_page *mp)
{
pgno_t ret;
- COPY_PGNO(ret, mp->mp_pgno);
+ COPY_PGNO(ret, MP_PGNO(mp));
return ret;
}
@@ -1601,13 +1618,13 @@ void
mdb_page_list(MDB_page *mp)
{
pgno_t pgno = mdb_dbg_pgno(mp);
- const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : "";
+ const char *type, *state = (MP_FLAGS(mp) & P_DIRTY) ? ", dirty" : "";
MDB_node *node;
unsigned int i, nkeys, nsize, total = 0;
MDB_val key;
DKBUF;
- switch (mp->mp_flags & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) {
+ switch (MP_FLAGS(mp) & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) {
case P_BRANCH: type = "Branch page"; break;
case P_LEAF:type = "Leaf page"; break;
case P_LEAF|P_SUBP: type = "Sub-page"; break;
@@ -1622,7 +1639,7 @@ mdb_page_list(MDB_page *mp)
pgno, ((MDB_meta *)METADATA(mp)