Fix a few 'gcc -fanalyzer' warnings.
[pwmd.git] / src / mem.c
blob857803cbe0150514cd5f9f8950fc8580e4afb4cb
1 /*
2 Copyright (C) 2006-2023 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #ifdef HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stddef.h>
30 #include "mem.h"
32 void *
33 xrealloc_gpgrt (void *p, size_t n)
35 if (n)
37 if (p)
38 return xrealloc (p, n);
40 return xmalloc (n);
43 xfree (p);
44 return NULL;
47 /* Borrowed from g10code:
48 * https://lists.gnupg.org/pipermail/gnupg-devel/2018-November/034060.html
50 void
51 wipememory (void *ptr, int c, size_t len)
53 #if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory)
54 (void)c;
55 SecureZeroMemory (ptr, len);
56 #elif defined(HAVE_EXPLICIT_BZERO)
57 (void)c;
58 explicit_bzero (ptr, len);
59 #elif defined(HAVE_MEMSET_S)
60 memset_s (ptr, len, c, len);
61 #else
62 /* Prevent compiler from optimizing away the call to memset by accessing
63 memset through volatile pointer. */
64 static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
65 memset_ptr (ptr, c, len);
66 #endif
69 #ifndef MEM_DEBUG
70 struct memchunk_s
72 size_t size;
73 char data[1];
74 } __attribute ((packed));
76 void
77 xfree (void *ptr)
79 struct memchunk_s *m;
80 void *p;
82 if (!ptr)
83 return;
85 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
86 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
87 wipememory (p, 0, m->size);
88 free (m);
91 void *
92 xmalloc (size_t size)
94 struct memchunk_s *m;
96 if (!size)
97 return NULL;
99 m = malloc (sizeof (struct memchunk_s)+size);
100 if (!m)
101 return NULL;
103 m->size = size;
104 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
107 void *
108 xcalloc (size_t nmemb, size_t size)
110 void *p;
111 struct memchunk_s *m;
113 m = malloc (sizeof (struct memchunk_s)+(nmemb*size));
114 if (!m)
115 return NULL;
117 m->size = nmemb*size;
118 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
119 memset (p, 0, m->size);
120 return p;
123 void *
124 xrealloc (void *ptr, size_t size)
126 void *p, *np;
127 struct memchunk_s *m, *mp;
128 size_t n;
130 if (!size && ptr)
132 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
133 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
134 wipememory (p, 0, m->size);
135 free (m);
136 return NULL;
138 else if (!ptr)
139 return xmalloc (size);
141 m = malloc (sizeof (struct memchunk_s)+size);
142 if (!m)
143 return NULL;
145 m->size = size;
146 np = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
148 mp = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
149 p = (void *)((char *)mp+(offsetof (struct memchunk_s, data)));
151 n = size > mp->size ? mp->size : size;
152 memcpy (np, p, n);
153 wipememory (p, 0, mp->size);
155 free (mp);
156 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
159 #endif