]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
libmisc: Add safer allocation functions
authorAlejandro Colomar <alx@kernel.org>
Sat, 4 Feb 2023 20:13:59 +0000 (21:13 +0100)
committerSerge Hallyn <serge@hallyn.com>
Fri, 24 Feb 2023 02:28:43 +0000 (20:28 -0600)
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/alloc.h
libmisc/alloc.c

index 9b1f8dc056de494ffb6c71c440d8e738a1a6e395..979588b4731b5d85876d5a720314a84a12e1c606 100644 (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_
 #define SHADOW_INCLUDE_LIB_MALLOC_H_
 
 
+#include <config.h>
+
+#include <assert.h>
+#include <errno.h>
 #include <stddef.h>
+#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;
+}
+
 
-/* xmalloc.c */
-extern /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size)
-  /*@ensures MaxSet(result) == (size - 1); @*/;
-extern /*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *);
+inline char *
+xstrdup(const char *str)
+{
+       return strcpy(XMALLOCARRAY(strlen(str) + 1, char), str);
+}
 
 
 #endif  // include guard
index 056d472ffb93fe4d9273436bc41d0f206c8ea2d3..962f45a1d90eb165c9710caef1d72f1b00e74dc7 100644 (file)
@@ -3,6 +3,7 @@
  * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
  * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
  * SPDX-FileCopyrightText: 2008       , Nicolas François
+ * SPDX-FileCopyrightText: 2023       , Alejandro Colomar <alx@kernel.org>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +12,7 @@
    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
    message better than a core dump...  --marekm
-   
+
    Yeh, but.  Remember that bailing out might leave the system in some
    bizarre state.  You really want to put in error checking, then add
    some back-out failure recovery code. -- jfh */
 
 #ident "$Id$"
 
-#include <stdio.h>
+#include "alloc.h"
+
 #include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+
 #include "defines.h"
 #include "prototypes.h"
 #include "shadowlog.h"
 
-/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size)
+
+extern inline void *xmalloc(size_t size);
+extern inline void *xmallocarray(size_t nmemb, size_t size);
+extern inline void *mallocarray(size_t nmemb, size_t size);
+extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
+extern inline char *xstrdup(const char *str);
+
+
+void *
+xcalloc(size_t nmemb, size_t size)
 {
-       void *ptr;
-
-       ptr = malloc (size);
-       if (NULL == ptr) {
-               (void) fprintf (log_get_logfd(),
-                               _("%s: failed to allocate memory: %s\n"),
-                               log_get_progname(), strerror (errno));
-               exit (13);
-       }
-       return ptr;
+       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);
 }