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