Annotation of src/usr.bin/sudo/alloc.c, Revision 1.5
1.1 millert 1: /*
1.5 ! millert 2: * Copyright (c) 1999-2003 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 millert 3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: *
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: *
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * 3. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * 4. Products derived from this software may not be called "Sudo" nor
20: * may "Sudo" appear in their names without specific prior written
21: * permission from the author.
22: *
23: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
26: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #include "config.h"
36:
1.3 millert 37: #include <sys/types.h>
38: #include <sys/param.h>
1.1 millert 39: #include <stdio.h>
40: #ifdef STDC_HEADERS
1.3 millert 41: # include <stdlib.h>
42: # include <stddef.h>
43: #else
44: # ifdef HAVE_STDLIB_H
45: # include <stdlib.h>
46: # endif
1.1 millert 47: #endif /* STDC_HEADERS */
48: #ifdef HAVE_STRING_H
1.3 millert 49: # include <string.h>
50: #else
51: # ifdef HAVE_STRINGS_H
52: # include <strings.h>
53: # endif
1.1 millert 54: #endif /* HAVE_STRING_H */
55: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
1.3 millert 56: # include <malloc.h>
1.1 millert 57: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
1.5 ! millert 58: #include <limits.h>
1.1 millert 59:
60: #include "sudo.h"
61:
62: #ifndef lint
1.5 ! millert 63: static const char rcsid[] = "$Sudo: alloc.c,v 1.18 2003/03/15 20:31:01 millert Exp $";
1.1 millert 64: #endif /* lint */
65:
1.5 ! millert 66: /*
! 67: * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
! 68: * could be signed (as it is on SunOS 4.x). This just means that
! 69: * emalloc2() and erealloc3() cannot allocate huge amounts on such a
! 70: * platform but that is OK since sudo doesn't need to do so anyway.
! 71: */
! 72: #ifndef SIZE_MAX
! 73: # ifdef SIZE_T_MAX
! 74: # define SIZE_MAX SIZE_T_MAX
! 75: # else
! 76: # ifdef INT_MAX
! 77: # define SIZE_MAX INT_MAX
! 78: # else
! 79: # define SIZE_MAX 0x7fffffff
! 80: # endif /* ULONG_MAX */
! 81: # endif /* SIZE_T_MAX */
! 82: #endif /* SIZE_MAX */
! 83:
1.4 millert 84: extern char **Argv; /* from sudo.c */
1.1 millert 85:
86: /*
87: * emalloc() calls the system malloc(3) and exits with an error if
88: * malloc(3) fails.
89: */
90: VOID *
91: emalloc(size)
92: size_t size;
93: {
94: VOID *ptr;
95:
1.5 ! millert 96: if (size == 0) {
! 97: (void) fprintf(stderr, "%s: internal error, tried to emalloc(0)\n",
! 98: Argv[0]);
! 99: exit(1);
! 100: }
! 101: if ((ptr = (VOID *) malloc(size)) == NULL) {
! 102: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
! 103: exit(1);
! 104: }
! 105: return(ptr);
! 106: }
! 107:
! 108: /*
! 109: * emalloc2() allocates nmemb * size bytes and exits with an error
! 110: * if overflow would occur or if the system malloc(3) fails.
! 111: */
! 112: VOID *
! 113: emalloc2(nmemb, size)
! 114: size_t nmemb;
! 115: size_t size;
! 116: {
! 117: VOID *ptr;
! 118:
! 119: if (nmemb == 0 || size == 0) {
! 120: (void) fprintf(stderr, "%s: internal error, tried to emalloc2(0)\n",
! 121: Argv[0]);
! 122: exit(1);
! 123: }
! 124: if (nmemb > SIZE_MAX / size) {
! 125: (void) fprintf(stderr, "%s: internal error, emalloc2() overflow\n",
! 126: Argv[0]);
! 127: exit(1);
! 128: }
! 129: size *= nmemb;
1.4 millert 130: if ((ptr = (VOID *) malloc(size)) == NULL) {
1.1 millert 131: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
132: exit(1);
133: }
134: return(ptr);
135: }
136:
137: /*
138: * erealloc() calls the system realloc(3) and exits with an error if
139: * realloc(3) fails. You can call erealloc() with a NULL pointer even
140: * if the system realloc(3) does not support this.
141: */
142: VOID *
143: erealloc(ptr, size)
144: VOID *ptr;
145: size_t size;
146: {
147:
1.5 ! millert 148: if (size == 0) {
! 149: (void) fprintf(stderr, "%s: internal error, tried to erealloc(0)\n",
! 150: Argv[0]);
! 151: exit(1);
! 152: }
! 153: ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
! 154: if (ptr == NULL) {
! 155: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
! 156: exit(1);
! 157: }
! 158: return(ptr);
! 159: }
! 160:
! 161: /*
! 162: * erealloc3() realloc(3)s nmemb * size bytes and exits with an error
! 163: * if overflow would occur or if the system malloc(3)/realloc(3) fails.
! 164: * You can call erealloc() with a NULL pointer even if the system realloc(3)
! 165: * does not support this.
! 166: */
! 167: VOID *
! 168: erealloc3(ptr, nmemb, size)
! 169: VOID *ptr;
! 170: size_t nmemb;
! 171: size_t size;
! 172: {
! 173:
! 174: if (nmemb == 0 || size == 0) {
! 175: (void) fprintf(stderr, "%s: internal error, tried to erealloc3(0)\n",
! 176: Argv[0]);
! 177: exit(1);
! 178: }
! 179: if (nmemb > SIZE_MAX / size) {
! 180: (void) fprintf(stderr, "%s: internal error, erealloc3() overflow\n",
! 181: Argv[0]);
! 182: exit(1);
! 183: }
! 184: size *= nmemb;
1.4 millert 185: ptr = ptr ? (VOID *) realloc(ptr, size) : (VOID *) malloc(size);
186: if (ptr == NULL) {
1.1 millert 187: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
188: exit(1);
189: }
190: return(ptr);
191: }
192:
193: /*
194: * estrdup() is like strdup(3) except that it exits with an error if
195: * malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal.
196: */
197: char *
198: estrdup(src)
199: const char *src;
200: {
201: char *dst = NULL;
1.5 ! millert 202: size_t size;
1.1 millert 203:
204: if (src != NULL) {
1.5 ! millert 205: size = strlen(src) + 1;
! 206: dst = (char *) emalloc(size);
! 207: (void) memcpy(dst, src, size);
1.1 millert 208: }
209: return(dst);
210: }
211:
212: /*
213: * easprintf() calls vasprintf() and exits with an error if vasprintf()
214: * returns -1 (out of memory).
215: */
1.2 millert 216: int
1.1 millert 217: #ifdef __STDC__
218: easprintf(char **ret, const char *fmt, ...)
219: #else
220: easprintf(va_alist)
221: va_dcl
222: #endif
223: {
224: int len;
225: va_list ap;
226: #ifdef __STDC__
227: va_start(ap, fmt);
228: #else
229: char **ret;
230: const char *fmt;
231:
232: va_start(ap);
233: ret = va_arg(ap, char **);
234: fmt = va_arg(ap, const char *);
235: #endif
236: len = vasprintf(ret, fmt, ap);
237: va_end(ap);
238:
239: if (len == -1) {
240: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
241: exit(1);
242: }
1.2 millert 243: return(len);
1.1 millert 244: }
245:
246: /*
247: * evasprintf() calls vasprintf() and exits with an error if vasprintf()
248: * returns -1 (out of memory).
249: */
1.2 millert 250: int
1.1 millert 251: evasprintf(ret, format, args)
252: char **ret;
253: const char *format;
254: va_list args;
255: {
1.2 millert 256: int len;
1.1 millert 257:
1.2 millert 258: if ((len = vasprintf(ret, format, args)) == -1) {
1.1 millert 259: (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
260: exit(1);
261: }
1.2 millert 262: return(len);
1.1 millert 263: }