lib: cbprintf: fix ubsan errors in cbvprintf_package (take 2)

First approach had to be reverted because it did not pass tests.
Take 2 attempts to use uintptr_t instead of a pointer and cast it
to the expected pointer when necessary.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruściński 2024-10-11 15:48:59 +02:00 committed by Henrik Brix Andersen
parent adeeb10f4f
commit 0a54922ba7

View file

@ -242,10 +242,10 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
#define STR_POS_MASK BIT_MASK(7)
/* Buffer offset abstraction for better code clarity. */
#define BUF_OFFSET ((uintptr_t)buf - (uintptr_t)buf0)
#define BUF_OFFSET (buf - (uintptr_t)buf0)
uint8_t *buf0 = packaged; /* buffer start (may be NULL) */
uint8_t *buf = buf0; /* current buffer position */
uintptr_t buf = (uintptr_t)buf0; /* current buffer position */
unsigned int size; /* current argument's size */
unsigned int align; /* current argument's required alignment */
uint8_t str_ptr_pos[16]; /* string pointer positions */
@ -355,7 +355,7 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
size = sizeof(int);
/* align destination buffer location */
buf = (void *)ROUND_UP(buf, align);
buf = ROUND_UP(buf, align);
/* make sure the data fits */
if (buf0 != NULL && BUF_OFFSET + size > len) {
@ -430,14 +430,14 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
}
/* align destination buffer location */
buf = (void *) ROUND_UP(buf, align);
buf = ROUND_UP(buf, align);
if (buf0 != NULL) {
/* make sure it fits */
if ((BUF_OFFSET + size) > len) {
return -ENOSPC;
}
if (Z_CBPRINTF_VA_STACK_LL_DBL_MEMCPY) {
memcpy(buf, (uint8_t *)&v, size);
memcpy((void *)buf, (uint8_t *)&v, size);
} else if (fmt[-1] == 'L') {
*(long double *)buf = v.ld;
} else {
@ -577,14 +577,14 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
size = sizeof(double);
}
/* align destination buffer location */
buf = (void *) ROUND_UP(buf, align);
buf = ROUND_UP(buf, align);
if (buf0 != NULL) {
/* make sure it fits */
if (BUF_OFFSET + size > len) {
return -ENOSPC;
}
if (Z_CBPRINTF_VA_STACK_LL_DBL_MEMCPY) {
memcpy(buf, (uint8_t *)&v, size);
memcpy((void *)buf, (uint8_t *)&v, size);
} else if (fmt[-1] == 'L') {
*(long double *)buf = v.ld;
} else {
@ -603,7 +603,7 @@ int cbvprintf_package(void *packaged, size_t len, uint32_t flags,
}
/* align destination buffer location */
buf = (void *) ROUND_UP(buf, align);
buf = ROUND_UP(buf, align);
/* make sure the data fits */
if ((buf0 != NULL) && (BUF_OFFSET + size) > len) {
@ -700,7 +700,7 @@ process_string:
if (buf0 != NULL) {
if (Z_CBPRINTF_VA_STACK_LL_DBL_MEMCPY) {
memcpy(buf, (uint8_t *)&v, sizeof(long long));
memcpy((void *)buf, (uint8_t *)&v, sizeof(long long));
} else {
*(long long *)buf = v;
}
@ -767,7 +767,7 @@ process_string:
return -ENOSPC;
}
/* store the pointer position prefix */
*buf = pos;
*(uint8_t *)buf = pos;
++buf;
}
}
@ -781,7 +781,8 @@ process_string:
if (rws_pos_en) {
size = 0;
*buf++ = str_ptr_arg[i];
*(uint8_t *)buf = str_ptr_arg[i];
++buf;
} else {
/* retrieve the string pointer */
s = *(char **)(buf0 + str_ptr_pos[i] * sizeof(int));
@ -796,10 +797,10 @@ process_string:
return -ENOSPC;
}
/* store the pointer position prefix */
*buf = str_ptr_pos[i];
*(uint8_t *)buf = str_ptr_pos[i];
++buf;
/* copy the string with its terminating '\0' */
memcpy(buf, (uint8_t *)s, size);
memcpy((void *)buf, (uint8_t *)s, size);
buf += size;
}