src/contrib/elftoolchain/elfcopy/sections.c underallocates for Elf64_Rela and Elf32_Rela?

Mark Johnston markjdb at gmail.com
Sun Jul 8 16:03:54 UTC 2018


On Sun, Jul 08, 2018 at 08:47:38AM -0700, Mark Millard via freebsd-toolchain wrote:
> src/contrib/elftoolchain/elfcopy/sections.c has and uses the macro:
> 
> 716	#define	COPYREL(REL, SZ) do {					\
> 717		if (nrels == 0) {					\
> 718			if ((REL##SZ = malloc(cap *			\
> 719			    sizeof(Elf##SZ##_Rel))) == NULL)		\
> 720				err(EXIT_FAILURE, "malloc failed");	\
> 721		}							\
> 722		if (nrels >= cap) {					\
> 723			cap *= 2;					\
> 724			if ((REL##SZ = realloc(REL##SZ, cap *		\
> 725			    sizeof(Elf##SZ##_Rel))) == NULL)		\
> 726				err(EXIT_FAILURE, "realloc failed");	\
> 727		}							\
> 728		REL##SZ[nrels].r_offset = REL.r_offset;			\
> 729		REL##SZ[nrels].r_info	= REL.r_info;			\
> 730		if (s->type == SHT_RELA)				\
> 731			rela##SZ[nrels].r_addend = rela.r_addend;	\
> 732		nrels++;						\
> 733	} while (0)
> 
> The context has:
> 
> 687		Elf32_Rel	*rel32;
> 688		Elf64_Rel	*rel64;
> 689		Elf32_Rela	*rela32;
> 690		Elf64_Rela	*rela64;
> 
> So for, say, COPYREL(rela,64), the macro uses sizeof(Elf64_Rel) instead
> of sizeof(ELF64_Rela) in malloc and realloc but Elf64_Rela is the
> larger structure of the two ELF64_ types (by also having .r_addend).
> 
> The scan build on ci.freebsd.org complains about this:
> 
> Result of 'realloc' is converted to a pointer of type 'Elf64_Rela', which is incompatible with sizeof operand type 'Elf64_Rel'
> 
> So far it does not look like a false-positive to me.

Looks like a valid bug to me.  I think the following patch is needed:

diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c
index b292d18693b4..92265289c7d1 100644
--- a/contrib/elftoolchain/elfcopy/sections.c
+++ b/contrib/elftoolchain/elfcopy/sections.c
@@ -716,13 +716,13 @@ filter_reloc(struct elfcopy *ecp, struct section *s)
 #define	COPYREL(REL, SZ) do {					\
 	if (nrels == 0) {					\
 		if ((REL##SZ = malloc(cap *			\
-		    sizeof(Elf##SZ##_Rel))) == NULL)		\
+		    sizeof(*REL##SZ))) == NULL)			\
 			err(EXIT_FAILURE, "malloc failed");	\
 	}							\
 	if (nrels >= cap) {					\
 		cap *= 2;					\
 		if ((REL##SZ = realloc(REL##SZ, cap *		\
-		    sizeof(Elf##SZ##_Rel))) == NULL)		\
+		    sizeof(*REL##SZ))) == NULL)			\
 			err(EXIT_FAILURE, "realloc failed");	\
 	}							\
 	REL##SZ[nrels].r_offset = REL.r_offset;			\


More information about the freebsd-toolchain mailing list