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