VirtualBox

source: vbox/trunk/src/VBox/Runtime/generic/memsafer-generic.cpp@ 106061

Last change on this file since 106061 was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/* $Id: memsafer-generic.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT - Memory Allocate for Sensitive Data, generic heap-based implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include "internal/iprt.h"
42#include <iprt/memsafer.h>
43
44#include <iprt/assert.h>
45#include <iprt/err.h>
46#include <iprt/string.h>
47
48
49/*********************************************************************************************************************************
50* Defined Constants And Macros *
51*********************************************************************************************************************************/
52/** Allocation size alignment. */
53#define RTMEMSAFER_ALIGN 16
54/** Padding after the block to avoid small overruns. */
55#define RTMEMSAFER_PAD_BEFORE 96
56/** Padding after the block to avoid small underruns. */
57#define RTMEMSAFER_PAD_AFTER 32
58
59
60/*********************************************************************************************************************************
61* Global Variables *
62*********************************************************************************************************************************/
63/** XOR scrabler value.
64 * @todo determine this at runtime */
65#if ARCH_BITS == 32
66static uintptr_t g_uScramblerXor = UINT32_C(0x867af88d);
67#elif ARCH_BITS == 64
68static uintptr_t g_uScramblerXor = UINT64_C(0xed95ecc99416d312);
69#else
70# error "Bad ARCH_BITS value"
71#endif
72
73
74
75RTDECL(int) RTMemSaferScramble(void *pv, size_t cb)
76{
77
78 AssertMsg(*(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE) == cb,
79 ("*pvStart=%#zx cb=%#zx\n", *(size_t *)((char *)pv- RTMEMSAFER_PAD_BEFORE), cb));
80
81 /* Note! This isn't supposed to be safe, just less obvious. */
82 uintptr_t *pu = (uintptr_t *)pv;
83 cb = RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN);
84 while (cb > 0)
85 {
86 *pu ^= g_uScramblerXor;
87 pu++;
88 cb -= sizeof(*pu);
89 }
90
91 return VINF_SUCCESS;
92}
93RT_EXPORT_SYMBOL(RTMemSaferScramble);
94
95
96RTDECL(int) RTMemSaferUnscramble(void *pv, size_t cb)
97{
98 AssertMsg(*(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE) == cb,
99 ("*pvStart=%#zx cb=%#zx\n", *(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE), cb));
100
101 /* Note! This isn't supposed to be safe, just less obvious. */
102 uintptr_t *pu = (uintptr_t *)pv;
103 cb = RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN);
104 while (cb > 0)
105 {
106 *pu ^= g_uScramblerXor;
107 pu++;
108 cb -= sizeof(*pu);
109 }
110
111 return VINF_SUCCESS;
112}
113RT_EXPORT_SYMBOL(RTMemSaferUnscramble);
114
115
116RTDECL(int) RTMemSaferAllocZExTag(void **ppvNew, size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW_DEF
117{
118 AssertPtrReturn(ppvNew, VERR_INVALID_PARAMETER);
119 *ppvNew = NULL;
120 AssertReturn(cb, VERR_INVALID_PARAMETER);
121 RT_NOREF_PV(pszTag);
122
123 /*
124 * We support none of the hard requirements passed thru flags.
125 */
126 if (fFlags == 0)
127 {
128 /*
129 * Don't request zeroed memory. We want random heap garbage in the
130 * padding zones, nothing that makes our allocations easier to find.
131 */
132 size_t cbUser = RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN);
133 void *pvNew = RTMemAlloc(cbUser + RTMEMSAFER_PAD_BEFORE + RTMEMSAFER_PAD_AFTER);
134 if (pvNew)
135 {
136#ifdef RT_STRICT /* For checking input in string builds. */
137 memset(pvNew, 0xad, RTMEMSAFER_PAD_BEFORE);
138 memset((char *)pvNew + RTMEMSAFER_PAD_BEFORE + cb, 0xda, RTMEMSAFER_PAD_AFTER + (cbUser - cb));
139 *(size_t *)pvNew = cb;
140#endif
141
142 void *pvUser = (char *)pvNew + RTMEMSAFER_PAD_BEFORE;
143 *ppvNew = pvUser;
144
145 /* You don't use this API for performance, so we always clean memory. */
146 RT_BZERO(pvUser, cb);
147
148 return VINF_SUCCESS;
149 }
150 return VERR_NO_MEMORY;
151 }
152 AssertReturn(!(fFlags & ~RTMEMSAFER_F_VALID_MASK), VERR_INVALID_FLAGS);
153 return VWRN_UNABLE_TO_SATISFY_REQUIREMENTS;
154}
155RT_EXPORT_SYMBOL(RTMemSaferAllocZExTag);
156
157
158RTDECL(void) RTMemSaferFree(void *pv, size_t cb) RT_NO_THROW_DEF
159{
160 if (pv)
161 {
162 Assert(cb); /* does not support openssl. */
163 void *pvStart = (char *)pv - RTMEMSAFER_PAD_BEFORE;
164 AssertMsg(*(size_t *)pvStart == cb, ("*pvStart=%#zx cb=%#zx\n", *(size_t *)pvStart, cb));
165 RTMemWipeThoroughly(pv, RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN), 3);
166 RTMemFree(pvStart);
167 }
168 else
169 Assert(cb == 0);
170}
171RT_EXPORT_SYMBOL(RTMemSaferFree);
172
173
174RTDECL(int) RTMemSaferReallocZExTag(size_t cbOld, void *pvOld, size_t cbNew, void **ppvNew, uint32_t fFlags, const char *pszTag) RT_NO_THROW_DEF
175{
176 /*
177 * We cannot let the heap move us around because we will be failing in our
178 * duty to clean things up. So, allocate a new block, copy over the old
179 * content, and free the old one.
180 */
181 int rc;
182 /* Real realloc. */
183 if (cbNew && cbOld)
184 {
185 AssertPtr(pvOld);
186 AssertMsg(*(size_t *)((char *)pvOld - RTMEMSAFER_PAD_BEFORE) == cbOld,
187 ("*pvStart=%#zx cbOld=%#zx\n", *(size_t *)((char *)pvOld - RTMEMSAFER_PAD_BEFORE), cbOld));
188
189 /*
190 * We support none of the hard requirements passed thru flags.
191 */
192 void *pvNew;
193 rc = RTMemSaferAllocZExTag(&pvNew, cbNew, fFlags, pszTag);
194 if (RT_SUCCESS(rc))
195 {
196 memcpy(pvNew, pvOld, RT_MIN(cbNew, cbOld));
197 RTMemSaferFree(pvOld, cbOld);
198 *ppvNew = pvNew;
199 }
200 }
201 /* First allocation. */
202 else if (!cbOld)
203 {
204 Assert(pvOld == NULL);
205 rc = RTMemSaferAllocZExTag(ppvNew, cbNew, fFlags, pszTag);
206 }
207 /* Free operation*/
208 else
209 {
210 RTMemSaferFree(pvOld, cbOld);
211 rc = VINF_SUCCESS;
212 }
213 return rc;
214}
215RT_EXPORT_SYMBOL(RTMemSaferReallocZExTag);
216
217
218RTDECL(void *) RTMemSaferAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
219{
220 void *pvNew = NULL;
221 int rc = RTMemSaferAllocZExTag(&pvNew, cb, 0 /*fFlags*/, pszTag);
222 if (RT_SUCCESS(rc))
223 return pvNew;
224 return NULL;
225}
226RT_EXPORT_SYMBOL(RTMemSaferAllocZTag);
227
228
229RTDECL(void *) RTMemSaferReallocZTag(size_t cbOld, void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_DEF
230{
231 void *pvNew = NULL;
232 int rc = RTMemSaferReallocZExTag(cbOld, pvOld, cbNew, &pvNew, 0 /*fFlags*/, pszTag);
233 if (RT_SUCCESS(rc))
234 return pvNew;
235 return NULL;
236}
237RT_EXPORT_SYMBOL(RTMemSaferReallocZTag);
238
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette