Subject: Re: pkg/6684: Package for PGP 5.0i
To: None <netbsd-bugs@netbsd.org>
From: Julian Coleman <J.D.Coleman@newcastle.ac.uk>
List: netbsd-bugs
Date: 01/05/1999 12:43:57
Unfortunately, pgp5.0, as shipped, does not run on NetBSD/sparc.  This is
a message I sent to the PGP bugs address a while ago (and received no reply).
Can the patch be added as patch-aa?

J

-- 
"Railways have always been plagued by politicians, and it is not hard to
think that Robert Stephenson had the right idea when he drove his engine
over one of them at the opening of the Liverpool & Manchester Railway"

 ---8<---------------------------- Cut here ---------------------------->8---

OS:		NetBSD 1.3
Hardware:	Sun Sparc
Problem:	Bus error caused by alignment failures

The memory alignment strategy for PGP 5.0i causes bus errors on NetBSD/Sparc
because 8 byte variables are not aligned on an 8 byte boundary.

In src/lib/pgp/helper/pgpMem.c:PGP_INTERNAL_ALLOC(), a header is added to
all malloc()'ed memory and the pointer returned is incremented by the size
of the header.  However, there are no constraints to see if this increment
is correctly aligned.

The problem might also occur on other OS's running on the Sparc.  A patch
is appended (based on one used for the Chimera web browser).

J

PS.  The exact problem is that 'off_t' is an 8 byte value, but the header
length is only a mulitple of 4.  Pgpe crashes at pgpFileMod.c:333, when it
tries to modify 'context->filesize'.

PPS.  Maybe 'long long' should also be in the union (e.g. for Solaris 2).

 ---8<---------------------------- Cut here ---------------------------->8---

*** src/lib/pgp/helper/pgpMem.c.orig	Mon Aug 11 01:05:32 1997
--- src/lib/pgp/helper/pgpMem.c	Thu Mar 26 12:34:39 1998
***************
*** 19,24 ****
--- 19,38 ----
  #include "pgpDebug.h"
  #include "pgpLeaks.h"
  
+ /*
+  * Make sure any memory chunks are correctly aligned.
+  * This can be forced by defining ALIGNSIZE (in bytes).
+  */
+ #ifndef ALIGNSIZE
+ typedef struct Alignment
+ {
+   union { int a; char *b; size_t c; off_t d; long e; } Align;
+ } Alignment;
+ #define MEMALIGN(x) ((x / sizeof(Alignment) + 1) * sizeof(Alignment))
+ #else
+ #define MEMALIGN(x) ((x / ALIGNSIZE + 1) * ALIGNSIZE)
+ #endif
+ 
  /* Fills allocated/deallocated memory with 0xDD's */
  #ifndef DEBUG_FILL_MEM
  #define DEBUG_FILL_MEM			DEBUG
***************
*** 69,79 ****
  };
  
  #define UserPtrToMemHeader(userPtr)		\
! 		((MemHeader *)((char *)(userPtr) - sizeof(MemHeader)))
  #define MemHeaderToUserPtr(hdrPtr)		\
!  	((void *)((char *)(hdrPtr) + sizeof(MemHeader)))
  #define FullBlockSize(userSize)			\
! 		(sizeof(MemHeader) + (userSize) + DEBUG_MEM_TAIL_MAGIC)
  
  /*
  * Defines the sequence of tail magic bytes. We want every byte to be
--- 83,93 ----
  };
  
  #define UserPtrToMemHeader(userPtr)		\
! 		((MemHeader *)((char *)(userPtr) - MEMALIGN(sizeof(MemHeader))))
  #define MemHeaderToUserPtr(hdrPtr)		\
!  	((void *)((char *)(hdrPtr) + MEMALIGN(sizeof(MemHeader))))
  #define FullBlockSize(userSize)			\
! 		(MEMALIGN(sizeof(MemHeader)) + (userSize) + DEBUG_MEM_TAIL_MAGIC)
  
  /*
  * Defines the sequence of tail magic bytes. We want every byte to be
***************
*** 269,275 ****
  	MemHeader *	header)
  {
  #if DEBUG_MEM_TAIL_MAGIC
! 	char *		tailMagic = (char *)header + sizeof(MemHeader) + header->size;
  	int			i;
  	
  	for (i = 0; i < DEBUG_MEM_TAIL_MAGIC; i++)
--- 283,289 ----
  	MemHeader *	header)
  {
  #if DEBUG_MEM_TAIL_MAGIC
! 	char *		tailMagic = (char *)header + MEMALIGN(sizeof(MemHeader)) + header->size;
  	int			i;
  	
  	for (i = 0; i < DEBUG_MEM_TAIL_MAGIC; i++)
***************
*** 287,294 ****
  	MemHeader *		header;
  	void *			userPtr;
  	
  	header = (MemHeader *)pgpPlatformAlloc(FullBlockSize(size));
! if (header == NULL)
  		return NULL;
  
  	MaybeFillMem(header, FullBlockSize(size));
--- 301,309 ----
  	MemHeader *		header;
  	void *			userPtr;
  	
+ 	size += (MEMALIGN(sizeof(MemHeader)) - (sizeof(MemHeader)));
  	header = (MemHeader *)pgpPlatformAlloc(FullBlockSize(size));
! 	if (header == NULL)
  		return NULL;
  
  	MaybeFillMem(header, FullBlockSize(size));
***************
*** 352,358 ****
  		if (newHeader == NULL)
  			return PGPERR_NOMEM;
  		pgpCopyMemory((void *)oldHeader, (void *)newHeader,
! 					sizeof(MemHeader) + oldSize);
  		MaybeFillMem(oldHeader, FullBlockSize(oldSize));
  		pgpPlatformFree(oldHeader);
  	}
--- 367,373 ----
  		if (newHeader == NULL)
  			return PGPERR_NOMEM;
  		pgpCopyMemory((void *)oldHeader, (void *)newHeader,
! 					MEMALIGN(sizeof(MemHeader)) + oldSize);
  		MaybeFillMem(oldHeader, FullBlockSize(oldSize));
  		pgpPlatformFree(oldHeader);
  	}