1 1.158 maxv /* $NetBSD: kern_malloc.c,v 1.158 2019/11/14 16:23:52 maxv Exp $ */ 2 1.9 cgd 3 1.1 cgd /* 4 1.8 cgd * Copyright (c) 1987, 1991, 1993 5 1.8 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.81 agc * 3. Neither the name of the University nor the names of its contributors 16 1.81 agc * may be used to endorse or promote products derived from this software 17 1.81 agc * without specific prior written permission. 18 1.81 agc * 19 1.81 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.81 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.81 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.81 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.81 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.81 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.81 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.81 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.81 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.81 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.81 agc * SUCH DAMAGE. 30 1.81 agc * 31 1.81 agc * @(#)kern_malloc.c 8.4 (Berkeley) 5/20/95 32 1.81 agc */ 33 1.81 agc 34 1.81 agc /* 35 1.81 agc * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 36 1.81 agc * 37 1.81 agc * Redistribution and use in source and binary forms, with or without 38 1.81 agc * modification, are permitted provided that the following conditions 39 1.81 agc * are met: 40 1.81 agc * 1. Redistributions of source code must retain the above copyright 41 1.81 agc * notice, this list of conditions and the following disclaimer. 42 1.81 agc * 2. Redistributions in binary form must reproduce the above copyright 43 1.81 agc * notice, this list of conditions and the following disclaimer in the 44 1.81 agc * documentation and/or other materials provided with the distribution. 45 1.1 cgd * 3. All advertising materials mentioning features or use of this software 46 1.1 cgd * must display the following acknowledgement: 47 1.1 cgd * This product includes software developed by the University of 48 1.1 cgd * California, Berkeley and its contributors. 49 1.1 cgd * 4. Neither the name of the University nor the names of its contributors 50 1.1 cgd * may be used to endorse or promote products derived from this software 51 1.1 cgd * without specific prior written permission. 52 1.1 cgd * 53 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 1.1 cgd * SUCH DAMAGE. 64 1.1 cgd * 65 1.32 fvdl * @(#)kern_malloc.c 8.4 (Berkeley) 5/20/95 66 1.1 cgd */ 67 1.64 lukem 68 1.139 rmind /* 69 1.139 rmind * Wrapper interface for obsolete malloc(9). 70 1.139 rmind */ 71 1.139 rmind 72 1.64 lukem #include <sys/cdefs.h> 73 1.158 maxv __KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.158 2019/11/14 16:23:52 maxv Exp $"); 74 1.1 cgd 75 1.7 mycroft #include <sys/param.h> 76 1.7 mycroft #include <sys/malloc.h> 77 1.134 para #include <sys/kmem.h> 78 1.148 maxv #include <sys/asan.h> 79 1.158 maxv #include <sys/msan.h> 80 1.148 maxv 81 1.139 rmind /* 82 1.139 rmind * Built-in malloc types. Note: ought to be removed. 83 1.139 rmind */ 84 1.139 rmind MALLOC_DEFINE(M_DEVBUF, "devbuf", "device driver memory"); 85 1.139 rmind MALLOC_DEFINE(M_DMAMAP, "DMA map", "bus_dma(9) structures"); 86 1.139 rmind MALLOC_DEFINE(M_FREE, "free", "should be on free list"); 87 1.139 rmind MALLOC_DEFINE(M_TEMP, "temp", "misc. temporary data buffers"); 88 1.139 rmind MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables"); 89 1.139 rmind MALLOC_DEFINE(M_FTABLE, "fragtbl", "fragment reassembly header"); 90 1.139 rmind MALLOC_DEFINE(M_UFSMNT, "UFS mount", "UFS mount structure"); 91 1.139 rmind MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure"); 92 1.139 rmind MALLOC_DEFINE(M_MRTABLE, "mrt", "multicast routing tables"); 93 1.27 thorpej 94 1.139 rmind /* 95 1.139 rmind * Header contains total size, including the header itself. 96 1.139 rmind */ 97 1.134 para struct malloc_header { 98 1.150 maxv size_t mh_size; 99 1.150 maxv #ifdef KASAN 100 1.150 maxv size_t mh_rqsz; 101 1.150 maxv #endif 102 1.139 rmind } __aligned(ALIGNBYTES + 1); 103 1.78 pk 104 1.1 cgd void * 105 1.154 martin kern_malloc(unsigned long reqsize, int flags) 106 1.1 cgd { 107 1.136 rmind const int kmflags = (flags & M_NOWAIT) ? KM_NOSLEEP : KM_SLEEP; 108 1.152 maxv #ifdef KASAN 109 1.154 martin const size_t origsize = reqsize; 110 1.152 maxv #endif 111 1.154 martin size_t size = reqsize; 112 1.138 drochner size_t allocsize, hdroffset; 113 1.134 para struct malloc_header *mh; 114 1.134 para void *p; 115 1.134 para 116 1.148 maxv kasan_add_redzone(&size); 117 1.148 maxv 118 1.138 drochner if (size >= PAGE_SIZE) { 119 1.146 martin if (size > (ULONG_MAX-PAGE_SIZE)) 120 1.146 martin allocsize = ULONG_MAX; /* this will fail later */ 121 1.146 martin else 122 1.146 martin allocsize = PAGE_SIZE + size; /* for page alignment */ 123 1.138 drochner hdroffset = PAGE_SIZE - sizeof(struct malloc_header); 124 1.138 drochner } else { 125 1.138 drochner allocsize = sizeof(struct malloc_header) + size; 126 1.138 drochner hdroffset = 0; 127 1.138 drochner } 128 1.138 drochner 129 1.134 para p = kmem_intr_alloc(allocsize, kmflags); 130 1.134 para if (p == NULL) 131 1.134 para return NULL; 132 1.1 cgd 133 1.158 maxv kmsan_mark(p, allocsize, KMSAN_STATE_UNINIT); 134 1.158 maxv kmsan_orig(p, allocsize, KMSAN_TYPE_MALLOC, __RET_ADDR); 135 1.158 maxv 136 1.134 para if ((flags & M_ZERO) != 0) { 137 1.134 para memset(p, 0, allocsize); 138 1.8 cgd } 139 1.138 drochner mh = (void *)((char *)p + hdroffset); 140 1.138 drochner mh->mh_size = allocsize - hdroffset; 141 1.150 maxv #ifdef KASAN 142 1.150 maxv mh->mh_rqsz = origsize; 143 1.150 maxv #endif 144 1.147 maxv mh++; 145 1.11 cgd 146 1.157 maxv kasan_mark(mh, origsize, size, KASAN_MALLOC_REDZONE); 147 1.148 maxv 148 1.147 maxv return mh; 149 1.1 cgd } 150 1.1 cgd 151 1.1 cgd void 152 1.140 dsl kern_free(void *addr) 153 1.1 cgd { 154 1.134 para struct malloc_header *mh; 155 1.48 thorpej 156 1.134 para mh = addr; 157 1.134 para mh--; 158 1.62 thorpej 159 1.156 maxv kasan_mark(addr, mh->mh_size - sizeof(struct malloc_header), 160 1.157 maxv mh->mh_size - sizeof(struct malloc_header), KASAN_MALLOC_REDZONE); 161 1.148 maxv 162 1.158 maxv if (mh->mh_size >= PAGE_SIZE + sizeof(struct malloc_header)) { 163 1.158 maxv kmsan_mark((char *)addr - PAGE_SIZE, 164 1.158 maxv mh->mh_size + PAGE_SIZE - sizeof(struct malloc_header), 165 1.158 maxv KMSAN_STATE_INITED); 166 1.138 drochner kmem_intr_free((char *)addr - PAGE_SIZE, 167 1.138 drochner mh->mh_size + PAGE_SIZE - sizeof(struct malloc_header)); 168 1.158 maxv } else { 169 1.158 maxv kmsan_mark(mh, mh->mh_size, KMSAN_STATE_INITED); 170 1.138 drochner kmem_intr_free(mh, mh->mh_size); 171 1.158 maxv } 172 1.20 cgd } 173 1.20 cgd 174 1.20 cgd void * 175 1.140 dsl kern_realloc(void *curaddr, unsigned long newsize, int flags) 176 1.20 cgd { 177 1.134 para struct malloc_header *mh; 178 1.72 thorpej unsigned long cursize; 179 1.20 cgd void *newaddr; 180 1.20 cgd 181 1.20 cgd /* 182 1.69 enami * realloc() with a NULL pointer is the same as malloc(). 183 1.20 cgd */ 184 1.20 cgd if (curaddr == NULL) 185 1.139 rmind return malloc(newsize, ksp, flags); 186 1.20 cgd 187 1.20 cgd /* 188 1.69 enami * realloc() with zero size is the same as free(). 189 1.20 cgd */ 190 1.20 cgd if (newsize == 0) { 191 1.77 thorpej free(curaddr, ksp); 192 1.139 rmind return NULL; 193 1.20 cgd } 194 1.59 thorpej 195 1.119 ad if ((flags & M_NOWAIT) == 0) { 196 1.118 yamt ASSERT_SLEEPABLE(); 197 1.119 ad } 198 1.20 cgd 199 1.134 para mh = curaddr; 200 1.134 para mh--; 201 1.20 cgd 202 1.150 maxv #ifdef KASAN 203 1.150 maxv cursize = mh->mh_rqsz; 204 1.150 maxv #else 205 1.136 rmind cursize = mh->mh_size - sizeof(struct malloc_header); 206 1.150 maxv #endif 207 1.20 cgd 208 1.20 cgd /* 209 1.20 cgd * If we already actually have as much as they want, we're done. 210 1.20 cgd */ 211 1.20 cgd if (newsize <= cursize) 212 1.139 rmind return curaddr; 213 1.20 cgd 214 1.20 cgd /* 215 1.20 cgd * Can't satisfy the allocation with the existing block. 216 1.20 cgd * Allocate a new one and copy the data. 217 1.20 cgd */ 218 1.77 thorpej newaddr = malloc(newsize, ksp, flags); 219 1.51 thorpej if (__predict_false(newaddr == NULL)) { 220 1.20 cgd /* 221 1.69 enami * malloc() failed, because flags included M_NOWAIT. 222 1.20 cgd * Return NULL to indicate that failure. The old 223 1.20 cgd * pointer is still valid. 224 1.20 cgd */ 225 1.139 rmind return NULL; 226 1.20 cgd } 227 1.34 perry memcpy(newaddr, curaddr, cursize); 228 1.20 cgd 229 1.20 cgd /* 230 1.20 cgd * We were successful: free the old allocation and return 231 1.20 cgd * the new one. 232 1.20 cgd */ 233 1.77 thorpej free(curaddr, ksp); 234 1.139 rmind return newaddr; 235 1.70 enami } 236