acrn-hypervisor/hypervisor/arch/x86/lib/memory.c
Yonghua Huang ade53aa53a hv: fix potential NULL pointer dereference in 'memcpy_s'
'd' should be checked before calling 'memset()'.

Tracked-On: #5359
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
2020-09-27 18:40:55 +08:00

62 lines
1.3 KiB
C

/*
* Copyright (C) 2018 Intel Corporation.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
static inline void memset_erms(void *base, uint8_t v, size_t n)
{
asm volatile("rep ; stosb"
: "+D"(base)
: "a" (v), "c"(n));
}
void *memset(void *base, uint8_t v, size_t n)
{
/*
* Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
* to use it when possible.
*/
if ((base != NULL) && (n != 0U)) {
memset_erms(base, v, n);
}
return base;
}
static inline void memcpy_erms(void *d, const void *s, size_t slen)
{
asm volatile ("rep; movsb"
: "=&D"(d), "=&S"(s)
: "c"(slen), "0" (d), "1" (s)
: "memory");
}
/*
* @brief Copies at most slen bytes from src address to dest address, up to dmax.
*
* INPUTS
*
* @param[in] d pointer to Destination address
* @param[in] dmax maximum length of dest
* @param[in] s pointer to Source address
* @param[in] slen maximum number of bytes of src to copy
*
* @return 0 for success and -1 for runtime-constraint violation.
*/
int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
{
int32_t ret = -1;
if ((d != NULL) && (s != NULL) && (dmax >= slen) && ((d > (s + slen)) || (s > (d + dmax)))) {
if (slen != 0U) {
memcpy_erms(d, s, slen);
}
ret = 0;
} else if (d != NULL) {
(void)memset(d, 0U, dmax);
}
return ret;
}