Problem with Object Size Checking and reallocarray
Jon Turney
jon.turney@dronecode.org.uk
Mon Mar 12 19:58:00 GMT 2018
// gcc test.c -o test.exe -g -O2 -Wp,-D_FORTIFY_SOURCE=2
//
// extracted from InputLineAddChar in xserver/xkb/maprules.c
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
const char *buf[128];
char *line = reallocarray(NULL, 128, 2);
// size of line is 128*2 = 256
printf("%zu\n", __builtin_object_size(line, 0));
memcpy(line, buf, 128);
// __mempcy_chk tests against size 2, and terminates
}
reallocarray() is annotated in stdlib.h with '__alloc_size(2)
__alloc_size(3)'
per [1], this doesn't seem to be the correct syntax when the size is the
product of the arguments, and the last alloc_size seems to be silently
winning.
If I change this to '__alloc_size((2,3))' (as in the patch attached),
__builtin_object_size doesn't seem to be a compile-time constant
anymore, and so memcpy() evaluates differently, so it's hard to be sure
that's actually correct...
[1] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
-------------- next part --------------
From 36fe1f9af2720247beb0dadaf089106faa85b453 Mon Sep 17 00:00:00 2001
From: Jon Turney <jon.turney@dronecode.org.uk>
Date: Mon, 12 Mar 2018 19:54:11 +0000
Subject: [PATCH] Correct alloc_size annotation on reallocarray()
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
---
newlib/libc/include/stdlib.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/newlib/libc/include/stdlib.h b/newlib/libc/include/stdlib.h
index ef0e4bdda..593760a12 100644
--- a/newlib/libc/include/stdlib.h
+++ b/newlib/libc/include/stdlib.h
@@ -140,8 +140,7 @@ void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t _compar);
int rand (void);
void * realloc (void *__r, size_t __size) _NOTHROW;
#if __BSD_VISIBLE
-void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
- __alloc_size(3);
+void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size((2,3));
void * reallocf (void *__r, size_t __size);
#endif
#if __BSD_VISIBLE || __XSI_VISIBLE >= 4
--
2.16.2
More information about the Newlib
mailing list