libmisc: Add safer allocation functions

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
Alejandro Colomar 2023-02-04 21:13:59 +01:00 committed by Serge Hallyn
parent 881c1d63a1
commit d81506de1e
2 changed files with 116 additions and 20 deletions

View File

@ -1,13 +1,82 @@
/*
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_ #ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
#define SHADOW_INCLUDE_LIB_MALLOC_H_ #define SHADOW_INCLUDE_LIB_MALLOC_H_
#include <stddef.h> #include <config.h>
/* xmalloc.c */ #include <assert.h>
extern /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size) #include <errno.h>
/*@ensures MaxSet(result) == (size - 1); @*/; #include <stddef.h>
extern /*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *); #include <stdint.h>
#include <stdlib.h>
#include "defines.h"
ATTR_MALLOC(free)
inline void *xmalloc(size_t size);
ATTR_MALLOC(free)
inline void *xmallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *mallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline char *xstrdup(const char *str);
ATTR_MALLOC(free)
void *xcalloc(size_t nmemb, size_t size);
ATTR_MALLOC(free)
void *xreallocarray(void *p, size_t nmemb, size_t size);
inline void *
xmalloc(size_t size)
{
return xmallocarray(1, size);
}
inline void *
xmallocarray(size_t nmemb, size_t size)
{
return xreallocarray(NULL, nmemb, size);
}
inline void *
mallocarray(size_t nmemb, size_t size)
{
return reallocarray(NULL, nmemb, size);
}
inline void *
reallocarrayf(void *p, size_t nmemb, size_t size)
{
void *q;
q = reallocarray(p, nmemb, size);
/* realloc(p, 0) is equivalent to free(p); avoid double free. */
if (q == NULL && nmemb != 0 && size != 0)
free(p);
return q;
}
inline char *
xstrdup(const char *str)
{
return strcpy(XMALLOCARRAY(strlen(str) + 1, char), str);
}
#endif // include guard #endif // include guard

View File

@ -3,6 +3,7 @@
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 , Nicolas François * SPDX-FileCopyrightText: 2008 , Nicolas François
* SPDX-FileCopyrightText: 2023 , Alejandro Colomar <alx@kernel.org>
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -11,7 +12,7 @@
to be worth copyrighting :-). I did that because a lot of code used to be worth copyrighting :-). I did that because a lot of code used
malloc and strdup without checking for NULL pointer, and I like some malloc and strdup without checking for NULL pointer, and I like some
message better than a core dump... --marekm message better than a core dump... --marekm
Yeh, but. Remember that bailing out might leave the system in some Yeh, but. Remember that bailing out might leave the system in some
bizarre state. You really want to put in error checking, then add bizarre state. You really want to put in error checking, then add
some back-out failure recovery code. -- jfh */ some back-out failure recovery code. -- jfh */
@ -20,27 +21,53 @@
#ident "$Id$" #ident "$Id$"
#include <stdio.h> #include "alloc.h"
#include <errno.h> #include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include "defines.h" #include "defines.h"
#include "prototypes.h" #include "prototypes.h"
#include "shadowlog.h" #include "shadowlog.h"
/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size)
{
void *ptr;
ptr = malloc (size); extern inline void *xmalloc(size_t size);
if (NULL == ptr) { extern inline void *xmallocarray(size_t nmemb, size_t size);
(void) fprintf (log_get_logfd(), extern inline void *mallocarray(size_t nmemb, size_t size);
_("%s: failed to allocate memory: %s\n"), extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
log_get_progname(), strerror (errno)); extern inline char *xstrdup(const char *str);
exit (13);
}
return ptr; void *
xcalloc(size_t nmemb, size_t size)
{
void *p;
p = calloc(nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
} }
/*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *str)
void *
xreallocarray(void *p, size_t nmemb, size_t size)
{ {
return strcpy (xmalloc (strlen (str) + 1), str); p = reallocarrayf(p, nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
} }