From 6aec7c673f25ff8339730cca45207aed0a6e7c42 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 8 Feb 2022 09:23:58 +0200 Subject: [PATCH] Add rreallocn() to librpmio public API rreallocn() is like realloc() but with multiplication protection. Inspired by glibc's reallocarray() but I dislike that name. While at it, add xmallocn() as a shortcut to rreallocn(NULL, ...) case. Based on initial patch by Demi Marie Obenour. --- rpmio/rpmmalloc.c | 13 +++++++++++++ rpmio/rpmutil.h | 4 ++++ system.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/rpmio/rpmmalloc.c b/rpmio/rpmmalloc.c index 5711cb5fa..455046b5a 100644 --- a/rpmio/rpmmalloc.c +++ b/rpmio/rpmmalloc.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "debug.h" @@ -58,6 +59,18 @@ void * rcalloc (size_t nmemb, size_t size) return value; } +void * rreallocn (void *ptr, size_t nmemb, size_t size) +{ + register void *value = NULL; + if (size == 0) size++; + if (nmemb == 0) nmemb++; + if (nmemb < SIZE_MAX / size) + value = realloc(ptr, nmemb * size); + if (value == NULL) + value = vmefail(size); + return value; +} + void * rrealloc (void *ptr, size_t size) { register void *value; diff --git a/rpmio/rpmutil.h b/rpmio/rpmutil.h index 591353e29..553712e1d 100644 --- a/rpmio/rpmutil.h +++ b/rpmio/rpmutil.h @@ -124,6 +124,10 @@ void * rmalloc(size_t size); RPM_GNUC_MALLOC RPM_GNUC_ALLOC_SIZE2(1,2) void * rcalloc(size_t nmemb, size_t size); +/* Like realloc() but with overflow protection */ +RPM_GNUC_MALLOC RPM_GNUC_ALLOC_SIZE2(2,3) +void * rreallocn(void * ptr, size_t nmemb, size_t size); + RPM_GNUC_ALLOC_SIZE(2) void * rrealloc(void *ptr, size_t size); diff --git a/system.h b/system.h index 8a09fd183..32b964b13 100644 --- a/system.h +++ b/system.h @@ -64,8 +64,10 @@ extern int fdatasync(int fildes); #include "rpmio/rpmutil.h" /* compatibility macros to avoid a mass-renaming all over the codebase */ #define xmalloc(_size) rmalloc((_size)) +#define xmallocn(_nmemb, _size) rreallocn(NULL, (_nmemb), (_size)) #define xcalloc(_nmemb, _size) rcalloc((_nmemb), (_size)) #define xrealloc(_ptr, _size) rrealloc((_ptr), (_size)) +#define xreallocn(_ptr, _size) rreallocn((_ptr), (_nmemb), (_size)) #define xstrdup(_str) rstrdup((_str)) #define _free(_ptr) rfree((_ptr))