[host] app: dont use pointers when realloc may have changed them

This code was completely broken and corrupts the stack, replace it with
something that is actually safe.
This commit is contained in:
Geoffrey McRae 2022-01-09 19:27:05 +11:00
parent c05282c38c
commit fd12d9901a

View File

@ -34,6 +34,7 @@
#include "common/stringutils.h" #include "common/stringutils.h"
#include "common/cpuinfo.h" #include "common/cpuinfo.h"
#include "common/util.h" #include "common/util.h"
#include "common/array.h"
#include <lgmp/host.h> #include <lgmp/host.h>
@ -532,115 +533,91 @@ typedef struct KVMFRUserData
} }
KVMFRUserData; KVMFRUserData;
static void * allocUserData(KVMFRUserData * dst, size_t need, bool consume) static bool appendData(KVMFRUserData * dst, const void * src, const size_t size)
{ {
size_t avail = dst->size - dst->used; if (size > dst->size - dst->used)
if (need > avail)
{ {
size_t newSize = dst->size; size_t newSize = dst->size + max(1024, size);
do
{
newSize += 1024;
avail = newSize - dst->used;
}
while(need > avail);
dst->data = realloc(dst->data, newSize); dst->data = realloc(dst->data, newSize);
if (!dst->data) if (!dst->data)
{ {
DEBUG_ERROR("failed to realloc"); DEBUG_ERROR("Out of memory");
return NULL; return false;
} }
memset(dst->data + dst->size, 0, newSize - dst->size); memset(dst->data + dst->size, 0, newSize - dst->size);
dst->size = newSize; dst->size = newSize;
} }
void * ret = dst->data + dst->used; memcpy(dst->data + dst->used, src, size);
if (consume) dst->used += size;
dst->used += need;
return ret;
}
static bool appendBuffer(KVMFRUserData * dst, KVMFRRecord * rec,
const void * src, size_t size)
{
void * mem = allocUserData(dst, size, true);
if (!mem)
return false;
memcpy(mem, src, size);
rec->size += size;
return true; return true;
} }
static bool newKVMFRData(KVMFRUserData * dst) static bool newKVMFRData(KVMFRUserData * dst)
{ {
KVMFRRecord * record; {
memset(dst, 0, sizeof(*dst)); KVMFR kvmfr =
{
KVMFR * kvmfr = allocUserData(dst, sizeof(*kvmfr), true); .magic = KVMFR_MAGIC,
if (!kvmfr) .version = KVMFR_VERSION,
return false; .features = os_hasSetCursorPos() ? KVMFR_FEATURE_SETCURSORPOS : 0
};
memcpy(kvmfr->magic, KVMFR_MAGIC, strncpy(kvmfr.hostver, BUILD_VERSION, sizeof(kvmfr.hostver) - 1);
min(sizeof(kvmfr->magic), sizeof(KVMFR_MAGIC))); appendData(dst, &kvmfr, sizeof(kvmfr));
kvmfr->version = KVMFR_VERSION; }
kvmfr->features = os_hasSetCursorPos() ? KVMFR_FEATURE_SETCURSORPOS : 0;
strncpy(kvmfr->hostver, BUILD_VERSION, sizeof(kvmfr->hostver) - 1);
{ {
if (!(record = allocUserData(dst, sizeof(*record), true))) int cpus, cores, sockets;
char model[1024];
if (!lgCPUInfo(model, sizeof(model), &cpus, &cores, &sockets))
return false; return false;
KVMFRRecord_VMInfo * vmInfo = allocUserData(dst, sizeof(*vmInfo), true); KVMFRRecord_VMInfo vmInfo =
if (!vmInfo) {
return false; .cpus = cpus,
.cores = cores,
record->type = KVMFR_RECORD_VMINFO; .sockets = sockets,
record->size = sizeof(*vmInfo); };
strncpy(vmInfo->capture, app.iface->shortName, sizeof(vmInfo->capture) - 1);
const uint8_t * uuid = os_getUUID(); const uint8_t * uuid = os_getUUID();
if (uuid) memcpy(vmInfo.uuid, uuid, 16);
memcpy(vmInfo->uuid, uuid, 16);
char * model = allocUserData(dst, 1024, false); strncpy(vmInfo.capture, app.iface->shortName, sizeof(vmInfo.capture) - 1);
if (!model)
return false;
int cpus, cores, sockets;
if (lgCPUInfo(model, 1024, &cpus, &cores, &sockets))
{
vmInfo->cpus = cpus;
vmInfo->cores = cores;
vmInfo->sockets = sockets;
const int modelLen = strlen(model) + 1; const int modelLen = strlen(model) + 1;
record->size += modelLen; const KVMFRRecord record =
dst->used += modelLen; {
} .type = KVMFR_RECORD_VMINFO,
.size = sizeof(vmInfo) + modelLen
};
if (!appendData(dst, &record, sizeof(record)) ||
!appendData(dst, &vmInfo, sizeof(vmInfo)) ||
!appendData(dst, model , modelLen ))
return false;
} }
{ {
if (!(record = allocUserData(dst, sizeof(*record), true))) KVMFRRecord_OSInfo osInfo =
return false; {
.os = os_getKVMFRType()
};
KVMFRRecord_OSInfo * osInfo = allocUserData(dst, sizeof(*osInfo), true);
if (!osInfo)
return false;
record->type = KVMFR_RECORD_OSINFO;
record->size = sizeof(*osInfo);
osInfo->os = os_getKVMFRType();
const char * osName = os_getOSName(); const char * osName = os_getOSName();
if (!osName) if (!osName)
osName = ""; osName = "";
const int osNameLen = strlen(osName) + 1;
if (!appendBuffer(dst, record, osName, strlen(osName) + 1)) KVMFRRecord record =
{
.type = KVMFR_RECORD_OSINFO,
.size = sizeof(osInfo) + osNameLen
};
if (!appendData(dst, &record, sizeof(record)) ||
!appendData(dst, &osInfo, sizeof(osInfo)) ||
!appendData(dst, osName , osNameLen))
return false; return false;
} }