Merge pull request #2904 from SChernykh/dev

Fixed unaligned memory accesses
This commit is contained in:
xmrig 2022-01-26 23:26:03 +07:00 committed by GitHub
commit 5de1609b7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 14 deletions

View file

@ -30,6 +30,7 @@
#include "base/net/stratum/Job.h" #include "base/net/stratum/Job.h"
#include "base/tools/Alignment.h"
#include "crypto/common/Nonce.h" #include "crypto/common/Nonce.h"
@ -77,7 +78,7 @@ public:
} }
else { else {
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
*nonce(i) += roundSize; writeUnaligned(nonce(i), readUnaligned(nonce(i)) + roundSize);
} }
} }
@ -136,11 +137,11 @@ inline bool xmrig::WorkerJob<1>::nextRound(uint32_t rounds, uint32_t roundSize)
return false; return false;
} }
if (nonceSize() == sizeof(uint64_t)) { if (nonceSize() == sizeof(uint64_t)) {
m_jobs[index()].nonce()[1] = n[1]; writeUnaligned(m_jobs[index()].nonce() + 1, readUnaligned(n + 1));
} }
} }
else { else {
*n += roundSize; writeUnaligned(n, readUnaligned(n) + roundSize);
} }
return true; return true;

View file

@ -23,6 +23,7 @@
#include "backend/cpu/Cpu.h" #include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuWorker.h" #include "backend/cpu/CpuWorker.h"
#include "base/tools/Alignment.h"
#include "base/tools/Chrono.h" #include "base/tools/Chrono.h"
#include "core/config/Config.h" #include "core/config/Config.h"
#include "core/Miner.h" #include "core/Miner.h"
@ -271,7 +272,7 @@ void xmrig::CpuWorker<N>::start()
uint32_t current_job_nonces[N]; uint32_t current_job_nonces[N];
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
current_job_nonces[i] = *m_job.nonce(i); current_job_nonces[i] = readUnaligned(m_job.nonce(i));
} }
# ifdef XMRIG_FEATURE_BENCHMARK # ifdef XMRIG_FEATURE_BENCHMARK

View file

@ -22,6 +22,7 @@
#include "backend/cuda/runners/CudaCnRunner.h" #include "backend/cuda/runners/CudaCnRunner.h"
#include "backend/cuda/wrappers/CudaDevice.h" #include "backend/cuda/wrappers/CudaDevice.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/tools/Alignment.h"
#include "base/tools/Chrono.h" #include "base/tools/Chrono.h"
#include "core/Miner.h" #include "core/Miner.h"
#include "crypto/common/Nonce.h" #include "crypto/common/Nonce.h"
@ -152,7 +153,7 @@ void xmrig::CudaWorker::start()
uint32_t foundNonce[16] = { 0 }; uint32_t foundNonce[16] = { 0 };
uint32_t foundCount = 0; uint32_t foundCount = 0;
if (!m_runner->run(*m_job.nonce(), &foundCount, foundNonce)) { if (!m_runner->run(readUnaligned(m_job.nonce()), &foundCount, foundNonce)) {
return; return;
} }

View file

@ -23,6 +23,7 @@
#include "backend/opencl/runners/tools/OclSharedData.h" #include "backend/opencl/runners/tools/OclSharedData.h"
#include "backend/opencl/runners/tools/OclSharedState.h" #include "backend/opencl/runners/tools/OclSharedState.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/tools/Alignment.h"
#include "base/tools/Chrono.h" #include "base/tools/Chrono.h"
#include "core/Miner.h" #include "core/Miner.h"
#include "crypto/common/Nonce.h" #include "crypto/common/Nonce.h"
@ -179,7 +180,7 @@ void xmrig::OclWorker::start()
const uint64_t t = Chrono::steadyMSecs(); const uint64_t t = Chrono::steadyMSecs();
try { try {
m_runner->run(*m_job.nonce(), results); m_runner->run(readUnaligned(m_job.nonce()), results);
} }
catch (std::exception &ex) { catch (std::exception &ex) {
printError(id(), ex.what()); printError(id(), ex.what());

View file

@ -68,6 +68,7 @@ set(HEADERS_BASE
src/base/net/tools/MemPool.h src/base/net/tools/MemPool.h
src/base/net/tools/NetBuffer.h src/base/net/tools/NetBuffer.h
src/base/net/tools/Storage.h src/base/net/tools/Storage.h
src/base/tools/Alignment.h
src/base/tools/Arguments.h src/base/tools/Arguments.h
src/base/tools/Baton.h src/base/tools/Baton.h
src/base/tools/bswap_64.h src/base/tools/bswap_64.h

View file

@ -30,6 +30,7 @@
#include "base/net/stratum/Job.h" #include "base/net/stratum/Job.h"
#include "base/tools/Alignment.h"
#include "base/tools/Buffer.h" #include "base/tools/Buffer.h"
#include "base/tools/Cvt.h" #include "base/tools/Cvt.h"
#include "base/tools/cryptonote/BlockTemplate.h" #include "base/tools/cryptonote/BlockTemplate.h"
@ -73,7 +74,7 @@ bool xmrig::Job::setBlob(const char *blob)
return false; return false;
} }
if (*nonce() != 0 && !m_nicehash) { if (readUnaligned(nonce()) != 0 && !m_nicehash) {
m_nicehash = true; m_nicehash = true;
} }

View file

@ -0,0 +1,53 @@
/* XMRig
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ALIGNMENT_H
#define XMRIG_ALIGNMENT_H
#include <type_traits>
#include <cstring>
namespace xmrig {
template<typename T>
inline T readUnaligned(const T* ptr)
{
static_assert(std::is_integral<T>::value, "Integer type required");
T result;
memcpy(&result, ptr, sizeof(T));
return result;
}
template<typename T>
inline void writeUnaligned(T* ptr, T data)
{
static_assert(std::is_integral<T>::value, "Integer type required");
memcpy(ptr, &data, sizeof(T));
}
} /* namespace xmrig */
#endif /* XMRIG_ALIGNMENT_H */

View file

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "base/tools/Alignment.h"
#include "crypto/common/Nonce.h" #include "crypto/common/Nonce.h"
@ -53,10 +54,10 @@ bool xmrig::Nonce::next(uint8_t index, uint32_t *nonce, uint32_t reserveCount, u
continue; continue;
} }
*nonce = (nonce[0] & ~mask) | counter; writeUnaligned(nonce, static_cast<uint32_t>((readUnaligned(nonce) & ~mask) | counter));
if (mask > 0xFFFFFFFFULL) { if (mask > 0xFFFFFFFFULL) {
nonce[1] = (nonce[1] & (~mask >> 32)) | (counter >> 32); writeUnaligned(nonce + 1, static_cast<uint32_t>((readUnaligned(nonce + 1) & (~mask >> 32)) | (counter >> 32)));
} }
return true; return true;

View file

@ -45,12 +45,12 @@ public:
inline JobResult(const Job &job, uint64_t nonce, const uint8_t *result, const uint8_t* header_hash = nullptr, const uint8_t *mix_hash = nullptr, const uint8_t* miner_signature = nullptr) : inline JobResult(const Job &job, uint64_t nonce, const uint8_t *result, const uint8_t* header_hash = nullptr, const uint8_t *mix_hash = nullptr, const uint8_t* miner_signature = nullptr) :
algorithm(job.algorithm()), algorithm(job.algorithm()),
index(job.index()),
clientId(job.clientId()), clientId(job.clientId()),
jobId(job.id()), jobId(job.id()),
backend(job.backend()), backend(job.backend()),
nonce(nonce), nonce(nonce),
diff(job.diff()), diff(job.diff())
index(job.index())
{ {
memcpy(m_result, result, sizeof(m_result)); memcpy(m_result, result, sizeof(m_result));
@ -70,12 +70,12 @@ public:
inline JobResult(const Job &job) : inline JobResult(const Job &job) :
algorithm(job.algorithm()), algorithm(job.algorithm()),
index(job.index()),
clientId(job.clientId()), clientId(job.clientId()),
jobId(job.id()), jobId(job.id()),
backend(job.backend()), backend(job.backend()),
nonce(0), nonce(0),
diff(0), diff(0)
index(job.index())
{ {
} }
@ -88,12 +88,12 @@ public:
inline const uint8_t *minerSignature() const { return m_hasMinerSignature ? m_minerSignature : nullptr; } inline const uint8_t *minerSignature() const { return m_hasMinerSignature ? m_minerSignature : nullptr; }
const Algorithm algorithm; const Algorithm algorithm;
const uint8_t index;
const String clientId; const String clientId;
const String jobId; const String jobId;
const uint32_t backend; const uint32_t backend;
const uint64_t nonce; const uint64_t nonce;
const uint64_t diff; const uint64_t diff;
const uint8_t index;
private: private:
uint8_t m_result[32] = { 0 }; uint8_t m_result[32] = { 0 };