From 8b4248529e71299961cb7ad3ec744be00f263b7d Mon Sep 17 00:00:00 2001
From: "Todd C. Miller" <Todd.Miller@courtesan.com>
Date: Wed, 12 Mar 2003 21:41:22 +0000
Subject: [PATCH] Add emalloc2() -- like calloc() but w/o the bzero and with
 error/oflow checking.

---
 alloc.c | 41 +++++++++++++++++++++++++++++++++++++++++
 sudo.h  |  1 +
 2 files changed, 42 insertions(+)

diff --git a/alloc.c b/alloc.c
index e2f50ff08..d09491517 100644
--- a/alloc.c
+++ b/alloc.c
@@ -55,6 +55,7 @@
 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
 # include <malloc.h>
 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <limits.h>
 
 #include "sudo.h"
 
@@ -62,6 +63,18 @@
 static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
+#ifndef SIZE_MAX
+# ifdef SIZE_T_MAX
+#  define SIZE_MAX	SIZE_T_MAX
+# else
+#  ifdef ULONG_MAX
+#   define SIZE_MAX	ULONG_MAX
+#  else
+#   define SIZE_MAX	((unsigned long)-1)
+#  endif /* ULONG_MAX */
+# endif /* SIZE_T_MAX */
+#endif /* SIZE_MAX */
+
 extern char **Argv;		/* from sudo.c */
 
 /*
@@ -86,6 +99,34 @@ emalloc(size)
     return(ptr);
 }
 
+/*
+ * emalloc2() allocates nmemb * size bytes and exits with an error
+ * if overflow would occur or if the system malloc(3) fails.
+ */
+VOID *
+emalloc2(nmemb, size)
+    size_t nmemb;
+    size_t size;
+{
+    VOID *ptr;
+
+    if (nmemb == 0 || size == 0) {
+	(void) fprintf(stderr, "%s: internal error, tried to malloc(0)\n",
+	    Argv[0]);
+	exit(1);
+    }
+    if (nmemb >= SIZE_MAX / size) {
+	(void) fprintf(stderr, "%s: internal error, emalloc2() overflow\n",
+	    Argv[0]);
+	exit(1);
+    }
+    if ((ptr = (VOID *) malloc(nmemb * size)) == NULL) {
+	(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+	exit(1);
+    }
+    return(ptr);
+}
+
 /*
  * erealloc() calls the system realloc(3) and exits with an error if
  * realloc(3) fails.  You can call erealloc() with a NULL pointer even
diff --git a/sudo.h b/sudo.h
index 884f8f80b..8201df7d2 100644
--- a/sudo.h
+++ b/sudo.h
@@ -212,6 +212,7 @@ void pam_attempt_auth	__P((void));
 int yyparse		__P((void));
 void pass_warn		__P((FILE *));
 VOID *emalloc		__P((size_t));
+VOID *emalloc2		__P((size_t, size_t));
 VOID *erealloc		__P((VOID *, size_t));
 char *estrdup		__P((const char *));
 int easprintf		__P((char **, const char *, ...));
-- 
2.40.0