1From aae03b7e626d5f62ab929d51d11352a5a2ff6b2d Mon Sep 17 00:00:00 2001 2From: Lei Maohui <leimaohui@cn.fujitsu.com> 3Date: Tue, 9 Jun 2015 11:11:48 +0900 4Subject: [PATCH 1/2] packlib.c: support dictionary byte order dependent 5 6The previous dict files are NOT byte-order independent, in fact they are 7probably ARCHITECTURE SPECIFIC. 8Create the dict files in big endian, and convert to host endian while 9load them. This could fix the endian issue on multiple platform. 10 11Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> 12Upstream-Status: Submitted [https://github.com/cracklib/cracklib/pull/41] 13 14We can't use the endian.h, htobe* and be*toh functions because they are 15not available on older versions of glibc, such as that found in RHEL 165.9. 17 18Change to checking endian and directly calling bswap_* as defined in 19byteswap.h. 20 21Signed-off-by: Mark Hatle <mark.hatle@windriver.com> 22 23Signed-off-by: Lei Maohui <leimaohui@cn.fujitsu.com> 24--- 25 lib/packlib.c | 214 +++++++++++++++++++++++++++++++++++++++++++++- 26 1 file changed, 210 insertions(+), 4 deletions(-) 27 28diff --git a/lib/packlib.c b/lib/packlib.c 29index 8acb7be..a9d8750 100644 30--- a/lib/packlib.c 31+++ b/lib/packlib.c 32@@ -16,6 +16,12 @@ 33 #ifdef HAVE_STDINT_H 34 #include <stdint.h> 35 #endif 36+ 37+#ifndef _BSD_SOURCE 38+#define _BSD_SOURCE /* See feature_test_macros(7) */ 39+#endif 40+#include <endian.h> 41+#include <byteswap.h> 42 #include "packer.h" 43 44 static const char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993"; 45@@ -45,6 +51,185 @@ typedef struct 46 char data_get[NUMWORDS][MAXWORDLEN]; 47 } PWDICT64; 48 49+enum{ 50+ en_is32, 51+ en_is64 52+}; 53+ 54+static int 55+IheaderHostToBigEndian(char *pHeader, int nBitType) 56+{ 57+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) 58+ { 59+ struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader; 60+ 61+ pHeader64->pih_magic = bswap_64(pHeader64->pih_magic); 62+ pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords); 63+ pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen); 64+ pHeader64->pih_pad = bswap_16(pHeader64->pih_pad); 65+ 66+#if DEBUG 67+ printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n", 68+ pHeader64->pih_magic, pHeader64->pih_numwords, 69+ pHeader64->pih_blocklen, pHeader64->pih_pad); 70+#endif 71+ } 72+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) 73+ { 74+ struct pi_header *pHeader32 = (struct pi_header*)pHeader; 75+ 76+ pHeader32->pih_magic = bswap_32(pHeader32->pih_magic); 77+ pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords); 78+ pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen); 79+ pHeader32->pih_pad = bswap_16(pHeader32->pih_pad); 80+ 81+#if DEBUG 82+ printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n", 83+ pHeader32->pih_magic, pHeader32->pih_numwords, 84+ pHeader32->pih_blocklen, pHeader32->pih_pad); 85+#endif 86+ } 87+ else if (__BYTE_ORDER == __LITTLE_ENDIAN) 88+ { 89+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); 90+ return (-1); 91+ } 92+ 93+ return 0; 94+} 95+ 96+static int 97+IheaderBigEndianToHost(char *pHeader, int nBitType) 98+{ 99+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) 100+ { 101+ struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader; 102+ 103+ pHeader64->pih_magic = bswap_64(pHeader64->pih_magic); 104+ pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords); 105+ pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen); 106+ pHeader64->pih_pad = bswap_16(pHeader64->pih_pad); 107+ 108+#if DEBUG 109+ printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n", 110+ pHeader64->pih_magic, pHeader64->pih_numwords, 111+ pHeader64->pih_blocklen, pHeader64->pih_pad); 112+#endif 113+ } 114+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) 115+ { 116+ struct pi_header *pHeader32 = (struct pi_header*)pHeader; 117+ 118+ pHeader32->pih_magic = bswap_32(pHeader32->pih_magic); 119+ pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords); 120+ pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen); 121+ pHeader32->pih_pad = bswap_16(pHeader32->pih_pad); 122+ 123+#if DEBUG 124+ printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n", 125+ pHeader32->pih_magic, pHeader32->pih_numwords, 126+ pHeader32->pih_blocklen, pHeader32->pih_pad); 127+#endif 128+ } 129+ else if (__BYTE_ORDER == __LITTLE_ENDIAN) 130+ { 131+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); 132+ return (-1); 133+ } 134+ 135+ return 0; 136+} 137+ 138+static int 139+HwmsHostToBigEndian(char *pHwms, int nLen,int nBitType) 140+{ 141+ int i = 0; 142+ 143+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) 144+ { 145+ uint64_t *pHwms64 = (uint64_t*)pHwms; 146+ 147+ for (i = 0; i < nLen / sizeof(uint64_t); i++) 148+ { 149+ *pHwms64 = bswap_64(*pHwms64); 150+ *pHwms64++; 151+ } 152+ 153+ } 154+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) 155+ { 156+ uint32_t *pHwms32 = (uint32_t*)pHwms; 157+ 158+ for (i = 0; i < nLen / sizeof(uint32_t); i++) 159+ { 160+ *pHwms32 = bswap_32(*pHwms32); 161+ *pHwms32++; 162+ } 163+ 164+ } 165+ else if (__BYTE_ORDER == __LITTLE_ENDIAN) 166+ { 167+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); 168+ return (-1); 169+ } 170+ 171+#if DEBUG 172+ for (i = 0; i < nLen; i+=8) 173+ { 174+ printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", 175+ nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF, 176+ pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF, 177+ pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF); 178+ } 179+#endif 180+ 181+ return 0; 182+} 183+ 184+static int 185+HwmsBigEndianToHost(char *pHwms, int nLen, int nBitType) 186+{ 187+ int i = 0; 188+ 189+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) 190+ { 191+ uint64_t *pHwms64 = (uint64_t*)pHwms; 192+ 193+ for (i = 0; i < nLen / sizeof(uint64_t); i++) 194+ { 195+ *pHwms64++ = bswap_64(*pHwms64); 196+ } 197+ 198+ } 199+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) 200+ { 201+ uint32_t *pHwms32 = (uint32_t*)pHwms; 202+ 203+ for (i = 0; i < nLen / sizeof(uint32_t); i++) 204+ { 205+ *pHwms32 = bswap_32(*pHwms32); 206+ *pHwms32++; 207+ } 208+ 209+ } 210+ else if (__BYTE_ORDER == __LITTLE_ENDIAN) 211+ { 212+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); 213+ return (-1); 214+ } 215+ 216+#if DEBUG 217+ for (i = 0; i < nLen; i+=8) 218+ { 219+ printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", 220+ nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF, 221+ pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF, 222+ pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF); 223+ } 224+#endif 225+ 226+ return 0; 227+} 228 229 static int 230 _PWIsBroken64(FILE *ifp) 231@@ -57,6 +242,7 @@ _PWIsBroken64(FILE *ifp) 232 return 0; 233 } 234 235+ IheaderBigEndianToHost((char *) &pdesc64.header, en_is64); 236 return (pdesc64.header.pih_magic == PIH_MAGIC); 237 } 238 239@@ -149,7 +335,11 @@ PWOpen(prefix, mode) 240 pdesc.header.pih_blocklen = NUMWORDS; 241 pdesc.header.pih_numwords = 0; 242 243- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp); 244+ struct pi_header tmpheader32; 245+ 246+ memcpy(&tmpheader32, &pdesc.header, sizeof(pdesc.header)); 247+ IheaderHostToBigEndian((char *) &tmpheader32, en_is32); 248+ fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, ifp); 249 } else 250 { 251 pdesc.flags &= ~PFOR_WRITE; 252@@ -173,6 +363,7 @@ PWOpen(prefix, mode) 253 return NULL; 254 } 255 256+ IheaderBigEndianToHost((char *) &pdesc.header, en_is32); 257 if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0)) 258 { 259 /* uh-oh. either a broken "64-bit" file or a garbage file. */ 260@@ -195,6 +386,7 @@ PWOpen(prefix, mode) 261 } 262 return NULL; 263 } 264+ IheaderBigEndianToHost((char *) &pdesc64.header, en_is64); 265 if (pdesc64.header.pih_magic != PIH_MAGIC) 266 { 267 /* nope, not "64-bit" after all */ 268@@ -290,6 +482,7 @@ PWOpen(prefix, mode) 269 { 270 pdesc.flags &= ~PFOR_USEHWMS; 271 } 272+ HwmsBigEndianToHost((char*)pdesc64.hwms, sizeof(pdesc64.hwms), en_is64); 273 for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++) 274 { 275 pdesc.hwms[i] = pdesc64.hwms[i]; 276@@ -299,6 +492,7 @@ PWOpen(prefix, mode) 277 { 278 pdesc.flags &= ~PFOR_USEHWMS; 279 } 280+ HwmsBigEndianToHost((char*)pdesc.hwms, sizeof(pdesc.hwms), en_is32); 281 #if DEBUG 282 for (i=1; i<=0xff; i++) 283 { 284@@ -332,7 +526,11 @@ PWClose(pwp) 285 return (-1); 286 } 287 288- if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp)) 289+ struct pi_header tmpheader32; 290+ 291+ memcpy(&tmpheader32, &pwp->header, sizeof(pwp->header)); 292+ IheaderHostToBigEndian((char *) &tmpheader32, en_is32); 293+ if (!fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, pwp->ifp)) 294 { 295 fprintf(stderr, "index magic fwrite failed\n"); 296 return (-1); 297@@ -351,7 +549,12 @@ PWClose(pwp) 298 printf("hwm[%02x] = %d\n", i, pwp->hwms[i]); 299 #endif 300 } 301- fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp); 302+ 303+ PWDICT tmp_pwp; 304+ 305+ memcpy(&tmp_pwp, pwp, sizeof(PWDICT)); 306+ HwmsHostToBigEndian(tmp_pwp.hwms, sizeof(tmp_pwp.hwms), en_is32); 307+ fwrite(tmp_pwp.hwms, 1, sizeof(tmp_pwp.hwms), pwp->wfp); 308 } 309 } 310 311@@ -405,7 +608,8 @@ PutPW(pwp, string) 312 313 datum = (uint32_t) ftell(pwp->dfp); 314 315- fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp); 316+ uint32_t tmpdatum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum; 317+ fwrite((char *) &tmpdatum, sizeof(tmpdatum), 1, pwp->ifp); 318 319 fputs(pwp->data_put[0], pwp->dfp); 320 putc(0, (FILE*) pwp->dfp); 321@@ -464,6 +668,7 @@ GetPW(pwp, number) 322 perror("(index fread failed)"); 323 return NULL; 324 } 325+ datum64 = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_64(datum64) : datum64; 326 datum = datum64; 327 } else { 328 if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0)) 329@@ -477,6 +682,7 @@ GetPW(pwp, number) 330 perror("(index fread failed)"); 331 return NULL; 332 } 333+ datum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum; 334 } 335 336 int r = 1; 337-- 3382.20.1 339 340