IPC status fields will be protected by an Adler-32 checksum too.
This commit is contained in:
parent
4385a2dfd9
commit
bf8ce486d5
@ -50,6 +50,21 @@ namespace MUtils
|
|||||||
static const size_t HDR_LEN = 40;
|
static const size_t HDR_LEN = 40;
|
||||||
static const size_t IPC_SLOTS = 128;
|
static const size_t IPC_SLOTS = 128;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
quint64 counter;
|
||||||
|
quint32 pos_wr;
|
||||||
|
quint32 pos_rd;
|
||||||
|
}
|
||||||
|
ipc_status_data_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ipc_status_data_t payload;
|
||||||
|
quint32 checksum;
|
||||||
|
}
|
||||||
|
ipc_status_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
quint32 command_id;
|
quint32 command_id;
|
||||||
@ -57,22 +72,20 @@ namespace MUtils
|
|||||||
char param[MUtils::IPCChannel::MAX_MESSAGE_LEN];
|
char param[MUtils::IPCChannel::MAX_MESSAGE_LEN];
|
||||||
quint64 timestamp;
|
quint64 timestamp;
|
||||||
}
|
}
|
||||||
ipc_data_t;
|
ipc_msg_data_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ipc_data_t payload;
|
ipc_msg_data_t payload;
|
||||||
quint32 checksum;
|
quint32 checksum;
|
||||||
}
|
}
|
||||||
ipc_msg_t;
|
ipc_msg_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char header[HDR_LEN];
|
char header[HDR_LEN];
|
||||||
quint64 counter;
|
ipc_status_t status;
|
||||||
quint32 pos_wr;
|
ipc_msg_t data[IPC_SLOTS];
|
||||||
quint32 pos_rd;
|
|
||||||
ipc_msg_t data[IPC_SLOTS];
|
|
||||||
}
|
}
|
||||||
ipc_t;
|
ipc_t;
|
||||||
}
|
}
|
||||||
@ -130,8 +143,11 @@ MUtils::IPCChannel::IPCChannel(const QString &applicationId, const quint32 &appV
|
|||||||
m_appVersionNo(appVersionNo),
|
m_appVersionNo(appVersionNo),
|
||||||
m_headerStr(QCryptographicHash::hash(MAKE_ID(applicationId, appVersionNo, channelId, "header").toLatin1(), QCryptographicHash::Sha1).toHex())
|
m_headerStr(QCryptographicHash::hash(MAKE_ID(applicationId, appVersionNo, channelId, "header").toLatin1(), QCryptographicHash::Sha1).toHex())
|
||||||
{
|
{
|
||||||
assert(m_headerStr.length() == HDR_LEN);
|
|
||||||
p->initialized = false;
|
p->initialized = false;
|
||||||
|
if(m_headerStr.length() != Internal::HDR_LEN)
|
||||||
|
{
|
||||||
|
MUTILS_THROW("Invalid header length has been detected!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MUtils::IPCChannel::~IPCChannel(void)
|
MUtils::IPCChannel::~IPCChannel(void)
|
||||||
@ -235,6 +251,7 @@ int MUtils::IPCChannel::initialize(void)
|
|||||||
{
|
{
|
||||||
memset(ptr, 0, sizeof(Internal::ipc_t));
|
memset(ptr, 0, sizeof(Internal::ipc_t));
|
||||||
memcpy(&ptr->header[0], m_headerStr.constData(), Internal::HDR_LEN);
|
memcpy(&ptr->header[0], m_headerStr.constData(), Internal::HDR_LEN);
|
||||||
|
ptr->status.checksum = Internal::adler32(ADLER_SEED, &ptr->status.payload, sizeof(Internal::ipc_status_data_t));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -288,21 +305,31 @@ bool MUtils::IPCChannel::send(const quint32 &command, const quint32 &flags, cons
|
|||||||
|
|
||||||
if(Internal::ipc_t *const ptr = reinterpret_cast<Internal::ipc_t*>(p->sharedmem->data()))
|
if(Internal::ipc_t *const ptr = reinterpret_cast<Internal::ipc_t*>(p->sharedmem->data()))
|
||||||
{
|
{
|
||||||
Internal::ipc_msg_t ipc_msg;
|
const quint32 status_checksum = Internal::adler32(ADLER_SEED, &ptr->status.payload, sizeof(Internal::ipc_status_data_t));
|
||||||
memset(&ipc_msg, 0, sizeof(Internal::ipc_msg_t));
|
if(status_checksum == ptr->status.checksum)
|
||||||
|
|
||||||
ipc_msg.payload.command_id = command;
|
|
||||||
ipc_msg.payload.flags = flags;
|
|
||||||
if(message)
|
|
||||||
{
|
{
|
||||||
strncpy_s(ipc_msg.payload.param, MAX_MESSAGE_LEN, message, _TRUNCATE);
|
Internal::ipc_msg_t ipc_msg;
|
||||||
}
|
memset(&ipc_msg, 0, sizeof(Internal::ipc_msg_t));
|
||||||
ipc_msg.payload.timestamp = ptr->counter++;
|
|
||||||
ipc_msg.checksum = Internal::adler32(ADLER_SEED, &ipc_msg.payload, sizeof(Internal::ipc_data_t));
|
|
||||||
|
|
||||||
memcpy(&ptr->data[ptr->pos_wr], &ipc_msg, sizeof(Internal::ipc_msg_t));
|
ipc_msg.payload.command_id = command;
|
||||||
ptr->pos_wr = (ptr->pos_wr + 1) % Internal::IPC_SLOTS;
|
ipc_msg.payload.flags = flags;
|
||||||
success = true;
|
if(message)
|
||||||
|
{
|
||||||
|
strncpy_s(ipc_msg.payload.param, MAX_MESSAGE_LEN, message, _TRUNCATE);
|
||||||
|
}
|
||||||
|
ipc_msg.payload.timestamp = ptr->status.payload.counter++;
|
||||||
|
ipc_msg.checksum = Internal::adler32(ADLER_SEED, &ipc_msg.payload, sizeof(Internal::ipc_msg_data_t));
|
||||||
|
|
||||||
|
memcpy(&ptr->data[ptr->status.payload.pos_wr], &ipc_msg, sizeof(Internal::ipc_msg_t));
|
||||||
|
ptr->status.payload.pos_wr = (ptr->status.payload.pos_wr + 1) % Internal::IPC_SLOTS;
|
||||||
|
ptr->status.checksum = Internal::adler32(ADLER_SEED, &ptr->status.payload, sizeof(Internal::ipc_status_data_t));
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("Corrupted IPC status detected -> skipping!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -363,25 +390,34 @@ bool MUtils::IPCChannel::read(quint32 &command, quint32 &flags, char *const mess
|
|||||||
|
|
||||||
if(Internal::ipc_t *const ptr = reinterpret_cast<Internal::ipc_t*>(p->sharedmem->data()))
|
if(Internal::ipc_t *const ptr = reinterpret_cast<Internal::ipc_t*>(p->sharedmem->data()))
|
||||||
{
|
{
|
||||||
success = true;
|
const quint32 status_checksum = Internal::adler32(ADLER_SEED, &ptr->status.payload, sizeof(Internal::ipc_status_data_t));
|
||||||
memcpy(&ipc_msg, &ptr->data[ptr->pos_rd], sizeof(Internal::ipc_msg_t));
|
if(status_checksum == ptr->status.checksum)
|
||||||
ptr->pos_rd = (ptr->pos_rd + 1) % Internal::IPC_SLOTS;
|
|
||||||
|
|
||||||
const quint32 expected_checksum = Internal::adler32(ADLER_SEED, &ipc_msg.payload, sizeof(Internal::ipc_data_t));
|
|
||||||
if((expected_checksum == ipc_msg.checksum) || (ipc_msg.payload.timestamp < ptr->counter))
|
|
||||||
{
|
{
|
||||||
command = ipc_msg.payload.command_id;
|
memcpy(&ipc_msg, &ptr->data[ptr->status.payload.pos_rd], sizeof(Internal::ipc_msg_t));
|
||||||
flags = ipc_msg.payload.flags;
|
ptr->status.payload.pos_rd = (ptr->status.payload.pos_rd + 1) % Internal::IPC_SLOTS;
|
||||||
strncpy_s(message, buffSize, ipc_msg.payload.param, _TRUNCATE);
|
ptr->status.checksum = Internal::adler32(ADLER_SEED, &ptr->status.payload, sizeof(Internal::ipc_status_data_t));
|
||||||
|
|
||||||
|
const quint32 msg_checksum = Internal::adler32(ADLER_SEED, &ipc_msg.payload, sizeof(Internal::ipc_msg_data_t));
|
||||||
|
if((msg_checksum == ipc_msg.checksum) || (ipc_msg.payload.timestamp < ptr->status.payload.counter))
|
||||||
|
{
|
||||||
|
command = ipc_msg.payload.command_id;
|
||||||
|
flags = ipc_msg.payload.flags;
|
||||||
|
strncpy_s(message, buffSize, ipc_msg.payload.param, _TRUNCATE);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("Malformed or corrupted IPC message, will be ignored!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning("Malformed or corrupted IPC message, will be ignored");
|
qWarning("Corrupted IPC status detected -> skipping!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning("Shared memory pointer is NULL -> unable to write data!");
|
qWarning("Shared memory pointer is NULL -> unable to read data!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!p->sharedmem->unlock())
|
if(!p->sharedmem->unlock())
|
||||||
|
Loading…
Reference in New Issue
Block a user