Bug#1118149: passwordsafe: Please cherry-pick upstream patch to fix unaligned access
Source: passwordsafe
Version: 1.21.0+dfsg-1.1
Severity: normal
Tags: patch upstream
User: debian-sparc@lists.debian.org
Usertags: sparc64
X-Debbugs-Cc: debian-sparc@lists.debian.org
Hi,
passwordsafe currently FTBFS on sparc64 due to unaligned access [1]:
The following tests FAILED:
1 - cli-test (Bus error)
2 - Coretests (Bus error)
Errors while running CTest
This has been fixed by the upstream developers in [2].
While the crash does not affect other architectures at first sight, this
bug might be related to the crash reported in #1071155 [3], so it might
be worth a try to include the fix from [2].
NB: Patches from GitHub pull request can be obtained by adding a ".patch"
suffix to the URL of the pull request in [2].
Thanks,
Adrian
> [1] https://buildd.debian.org/status/fetch.php?pkg=passwordsafe&arch=sparc64&ver=1.21.0%2Bdfsg-1.1&stamp=1757581195&raw=0
> [2] https://github.com/pwsafe/pwsafe/pull/1623
> [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1071155
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
>From d07604bd3a490d7624fc0e3b381d507ea63a3141 Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 17:22:05 +0300
Subject: [PATCH 1/6] sparc64 - Fixed alignment problem in
PWSrand::NextRandBlock()
There are probably more...
---
src/core/PWSrand.cpp | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/core/PWSrand.cpp b/src/core/PWSrand.cpp
index be324123c7..9813469fd6 100644
--- a/src/core/PWSrand.cpp
+++ b/src/core/PWSrand.cpp
@@ -64,14 +64,21 @@ void PWSrand::NextRandBlock()
SHA256 s;
s.Update(K, sizeof(K));
s.Final(R);
- unsigned int *Kp = reinterpret_cast<unsigned int *>(K);
- unsigned int *Rp = reinterpret_cast<unsigned int *>(R);
- const int N = SHA256::HASHLEN / sizeof(uint32);
- Kp[0]++;
+ constexpr int N = SHA256::HASHLEN / sizeof(uint32);
+
+ // Use temporary buffers to avoid alignment issues
+ uint32 Ktemp[N], Rtemp[N];
+
+ std::memcpy(Ktemp, K, sizeof(Ktemp));
+ std::memcpy(Rtemp, R, sizeof(Rtemp));
+
+ Ktemp[0]++;
for (int32 i = 0; i < N; i++)
- Kp[i] += Rp[i];
+ Ktemp[i] += Rtemp[i];
+
+ std::memcpy(K, Ktemp, sizeof(Ktemp));
}
void PWSrand::GetRandomData( void * const buffer, unsigned long length )
>From 9860c33a5c6fb001b53d4beaa6d215f289dbad1c Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 17:39:21 +0300
Subject: [PATCH 2/6] Now compiles under Linux...
---
src/core/PWSrand.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/PWSrand.cpp b/src/core/PWSrand.cpp
index 9813469fd6..93c0f358aa 100644
--- a/src/core/PWSrand.cpp
+++ b/src/core/PWSrand.cpp
@@ -6,6 +6,7 @@
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/
#include <limits>
+#include <cstring> // for std::memcpy
#include "os/rand.h"
#include "PwsPlatform.h"
>From 1a188c451cf3e042a23846f525603b2d32e98fef Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 18:01:22 +0300
Subject: [PATCH 3/6] sparc64 - Fixed alignment problem in
CItemData::DeSerializePlainText()
---
src/core/ItemData.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/core/ItemData.cpp b/src/core/ItemData.cpp
index 74c716b122..456666b772 100644
--- a/src/core/ItemData.cpp
+++ b/src/core/ItemData.cpp
@@ -24,7 +24,7 @@
#include "os/pws_tchar.h"
#include "os/utf8conv.h"
-#include <ctime>
+#include <cstring>
#include <sstream>
#include <iomanip>
#include <algorithm>
@@ -2068,7 +2068,8 @@ bool CItemData::DeSerializePlainText(const std::vector<char> &v)
return true; // happy end
}
- uint32 len = *(reinterpret_cast<const uint32 *>(&(*iter)));
+ uint32 len = 0;
+ std::memcpy(&len, &(*iter), sizeof(len));
ASSERT(len < v.size()); // sanity check
iter += sizeof(uint32);
>From e1d3da7992e9ab76ea695861f49aa56683d37e44 Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 18:06:50 +0300
Subject: [PATCH 4/6] sparc64 - Fixed unrelated sanity check in
CItemData::DeSerializePlainText()
---
src/core/ItemData.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/ItemData.cpp b/src/core/ItemData.cpp
index 456666b772..1d6eee13ca 100644
--- a/src/core/ItemData.cpp
+++ b/src/core/ItemData.cpp
@@ -2053,7 +2053,7 @@ bool CItemData::DeSerializePlainText(const std::vector<char> &v)
while (iter != v.end()) {
unsigned char type = *iter++;
- if (static_cast<uint32>(distance(v.end(), iter)) < sizeof(uint32)) {
+ if (static_cast<uint32>(distance(iter, v.end())) < sizeof(uint32)) {
ASSERT(0); // type must ALWAYS be followed by length
return false;
}
>From 6d1fa4091f13ba4710d485705074f446c1c530e6 Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 18:17:37 +0300
Subject: [PATCH 5/6] sparc64 - Fixed HOTP::Generate()
---
src/core/crypto/hotp.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/core/crypto/hotp.h b/src/core/crypto/hotp.h
index 21fedcb773..b8098438d3 100644
--- a/src/core/crypto/hotp.h
+++ b/src/core/crypto/hotp.h
@@ -13,6 +13,7 @@
#include <vector>
#include <cmath>
+#include <cstring> // for memcpy
#include "../Util.h"
#include "hmac.h"
@@ -39,7 +40,8 @@ class HOTP
Digest digest(HMACGenerator::HASH_LENGTH);
hmacGenerator.Final(&digest[0]);
int index = digest[HMACGenerator::HASH_LENGTH - 1] & 0x0F;
- uint32_t code = *reinterpret_cast<uint32_t*>(&digest[0] + index);
+ uint32_t code = 0;
+ std::memcpy(&code, &digest[0] + index, sizeof(code));
#ifdef PWS_LITTLE_ENDIAN
byteswap(code);
#endif
>From 2a0a815280e0a0f8297f5809a323d8ccb78ebc33 Mon Sep 17 00:00:00 2001
From: ronys <ronys@pwsafe.org>
Date: Sun, 12 Oct 2025 18:27:20 +0300
Subject: [PATCH 6/6] sparc64 - Fixed PWSrand::RandUInt()
---
src/core/PWSrand.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/PWSrand.cpp b/src/core/PWSrand.cpp
index 93c0f358aa..83e1dcfbd3 100644
--- a/src/core/PWSrand.cpp
+++ b/src/core/PWSrand.cpp
@@ -128,8 +128,8 @@ unsigned int PWSrand::RandUInt()
ibRandomData = 0;
}
- const unsigned int u =
- *(reinterpret_cast<uint32 *>(rgbRandomData + ibRandomData));
+ unsigned int u = 0;
+ std::memcpy(&u, rgbRandomData + ibRandomData, sizeof(uint32));
ibRandomData += sizeof(uint32);
return u;
}
Reply to: