Re: openldap: FTBFS on sparc64 due to unaligned access in testsuite

2022-11-17 Thread John Paul Adrian Glaubitz

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 

Re: openldap: FTBFS on sparc64 due to unaligned access in testsuite

2022-10-25 Thread John Paul Adrian Glaubitz

Hi!

On 9/20/22 00:16, John Paul Adrian Glaubitz wrote:

openldap FTBFS on sparc64 due to an unaligned access in the testsuite:


Test succeeded
test000-rootdse completed OK for mdb after 1 seconds.



Starting test001-slapadd for mdb...

running defines.sh
Running slapadd to build slapd database...
Bus error
slapadd failed (138)!

test001-slapadd failed for mdb after 0 seconds

(exit 138)


It looks like this issue has been silently fixed in OpenLDAP 2.6.x.

It's no longer reproducible on git master and upstream closed the bug.

Adrian

--
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913