~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to storage/tokudb/ft-index/portability/os_malloc.cc

  • Committer: Package Import Robot
  • Author(s): James Page, Otto Kekäläinen
  • Date: 2014-02-17 16:51:52 UTC
  • mfrom: (2.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140217165152-k315d3175g865kkx
Tags: 5.5.35-1
[ Otto Kekäläinen ]
* New upstream release, fixing the following security issues:
  - Buffer overflow in client/mysql.cc (Closes: #737597).
    - CVE-2014-0001
  - http://www.oracle.com/technetwork/topics/security/cpujan2014-1972949.html
    - CVE-2013-5891
    - CVE-2013-5908
    - CVE-2014-0386
    - CVE-2014-0393
    - CVE-2014-0401
    - CVE-2014-0402
    - CVE-2014-0412
    - CVE-2014-0420
    - CVE-2014-0437
* Upstream https://mariadb.atlassian.net/browse/MDEV-4902
  fixes compatibility with Bison 3.0 (Closes: #733002)
* Updated Russian debconf translation (Closes: #734426)
* Updated Japanese debconf translation (Closes: #735284)
* Updated French debconf translation (Closes: #736480)
* Renamed SONAME properly (Closes: #732967)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 
2
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
 
3
#ident "$Id$"
 
4
 
 
5
/*
 
6
COPYING CONDITIONS NOTICE:
 
7
 
 
8
  This program is free software; you can redistribute it and/or modify
 
9
  it under the terms of version 2 of the GNU General Public License as
 
10
  published by the Free Software Foundation, and provided that the
 
11
  following conditions are met:
 
12
 
 
13
      * Redistributions of source code must retain this COPYING
 
14
        CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
 
15
        DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
 
16
        PATENT MARKING NOTICE (below), and the PATENT RIGHTS
 
17
        GRANT (below).
 
18
 
 
19
      * Redistributions in binary form must reproduce this COPYING
 
20
        CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
 
21
        DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
 
22
        PATENT MARKING NOTICE (below), and the PATENT RIGHTS
 
23
        GRANT (below) in the documentation and/or other materials
 
24
        provided with the distribution.
 
25
 
 
26
  You should have received a copy of the GNU General Public License
 
27
  along with this program; if not, write to the Free Software
 
28
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
29
  02110-1301, USA.
 
30
 
 
31
COPYRIGHT NOTICE:
 
32
 
 
33
  TokuDB, Tokutek Fractal Tree Indexing Library.
 
34
  Copyright (C) 2007-2013 Tokutek, Inc.
 
35
 
 
36
DISCLAIMER:
 
37
 
 
38
  This program is distributed in the hope that it will be useful, but
 
39
  WITHOUT ANY WARRANTY; without even the implied warranty of
 
40
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
41
  General Public License for more details.
 
42
 
 
43
UNIVERSITY PATENT NOTICE:
 
44
 
 
45
  The technology is licensed by the Massachusetts Institute of
 
46
  Technology, Rutgers State University of New Jersey, and the Research
 
47
  Foundation of State University of New York at Stony Brook under
 
48
  United States of America Serial No. 11/760379 and to the patents
 
49
  and/or patent applications resulting from it.
 
50
 
 
51
PATENT MARKING NOTICE:
 
52
 
 
53
  This software is covered by US Patent No. 8,185,551.
 
54
  This software is covered by US Patent No. 8,489,638.
 
55
 
 
56
PATENT RIGHTS GRANT:
 
57
 
 
58
  "THIS IMPLEMENTATION" means the copyrightable works distributed by
 
59
  Tokutek as part of the Fractal Tree project.
 
60
 
 
61
  "PATENT CLAIMS" means the claims of patents that are owned or
 
62
  licensable by Tokutek, both currently or in the future; and that in
 
63
  the absence of this license would be infringed by THIS
 
64
  IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
 
65
 
 
66
  "PATENT CHALLENGE" shall mean a challenge to the validity,
 
67
  patentability, enforceability and/or non-infringement of any of the
 
68
  PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
 
69
 
 
70
  Tokutek hereby grants to you, for the term and geographical scope of
 
71
  the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
 
72
  irrevocable (except as stated in this section) patent license to
 
73
  make, have made, use, offer to sell, sell, import, transfer, and
 
74
  otherwise run, modify, and propagate the contents of THIS
 
75
  IMPLEMENTATION, where such license applies only to the PATENT
 
76
  CLAIMS.  This grant does not include claims that would be infringed
 
77
  only as a consequence of further modifications of THIS
 
78
  IMPLEMENTATION.  If you or your agent or licensee institute or order
 
79
  or agree to the institution of patent litigation against any entity
 
80
  (including a cross-claim or counterclaim in a lawsuit) alleging that
 
81
  THIS IMPLEMENTATION constitutes direct or contributory patent
 
82
  infringement, or inducement of patent infringement, then any rights
 
83
  granted to you under this License shall terminate as of the date
 
84
  such litigation is filed.  If you or your agent or exclusive
 
85
  licensee institute or order or agree to the institution of a PATENT
 
86
  CHALLENGE, then Tokutek may terminate any rights granted to you
 
87
  under this License.
 
88
*/
 
89
 
 
90
#ident "Copyright (c) 2007-2013 Tokutek Inc.  All rights reserved."
 
91
 
 
92
#include "toku_config.h"
 
93
 
 
94
#include <toku_portability.h>
 
95
#include <stdlib.h>
 
96
//#include <jemalloc/include/jemalloc/jemalloc.h>
 
97
#if defined(HAVE_MALLOC_H)
 
98
# include <malloc.h>
 
99
#elif defined(HAVE_SYS_MALLOC_H)
 
100
# include <sys/malloc.h>
 
101
#endif
 
102
#include <dlfcn.h>
 
103
 
 
104
#include <string.h>
 
105
 
 
106
// #define this to use a version of os_malloc that helps to debug certain features.
 
107
// This version uses the real malloc (so that valgrind should still work) but it forces things to be slightly
 
108
// misaligned (in particular, avoiding 512-byte alignment if possible, to find situations where O_DIRECT will fail.
 
109
// #define USE_DEBUGGING_MALLOCS
 
110
 
 
111
#ifdef USE_DEBUGGING_MALLOCS
 
112
#include <pthread.h>
 
113
 
 
114
// Make things misaligned on 512-byte boundaries
 
115
static size_t malloced_now_count=0, malloced_now_size=0;
 
116
struct malloc_pair {
 
117
    void *returned_pointer;
 
118
    void *true_pointer;
 
119
    size_t requested_size = 0;
 
120
};
 
121
static struct malloc_pair *malloced_now;
 
122
static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
 
123
 
 
124
static void malloc_lock(void) {
 
125
    int r = pthread_mutex_lock(&malloc_mutex);
 
126
    assert(r==0);
 
127
}
 
128
static void malloc_unlock(void) {
 
129
    int r = pthread_mutex_unlock(&malloc_mutex);
 
130
    assert(r==0);
 
131
}
 
132
 
 
133
static void push_to_malloced_memory(void *returned_pointer, void *true_pointer, size_t requested_size) {
 
134
    malloc_lock();
 
135
    if (malloced_now_count == malloced_now_size) {
 
136
        malloced_now_size = 2*malloced_now_size + 1;
 
137
        malloced_now = (struct malloc_pair *)realloc(malloced_now, malloced_now_size * sizeof(*malloced_now));
 
138
    }
 
139
    malloced_now[malloced_now_count].returned_pointer = returned_pointer;
 
140
    malloced_now[malloced_now_count].true_pointer     = true_pointer;
 
141
    malloced_now[malloced_now_count].requested_size   = requested_size;
 
142
    malloced_now_count++;
 
143
    malloc_unlock();
 
144
}
 
145
 
 
146
static struct malloc_pair *find_malloced_pair(const void *p)
 
147
// Requires: Lock must be held before calling.
 
148
{
 
149
    for (size_t i=0; i<malloced_now_count; i++) {
 
150
        if (malloced_now[i].returned_pointer==p) return &malloced_now[i];
 
151
    }
 
152
    return 0;
 
153
}
 
154
 
 
155
void *os_malloc(size_t size) {
 
156
    void  *raw_ptr   = malloc(size+16); // allocate 16 extra bytes
 
157
    size_t raw_ptr_i = (size_t) raw_ptr; 
 
158
    if (raw_ptr_i%512==0) {
 
159
        push_to_malloced_memory(16+(char*)raw_ptr, raw_ptr, size);
 
160
        return 16+(char*)raw_ptr;
 
161
    } else {
 
162
        push_to_malloced_memory(raw_ptr,    raw_ptr, size);
 
163
        return raw_ptr;
 
164
    }
 
165
}
 
166
 
 
167
void *os_malloc_aligned(size_t alignment, size_t size)
 
168
// Effect: Perform a malloc(size) with the additional property that the returned pointer is a multiple of ALIGNMENT.
 
169
// Requires: alignment is a power of two.
 
170
{
 
171
    void *p;
 
172
    int r = posix_memalign(&p, alignment, size);
 
173
    if (r != 0) {
 
174
        errno = r;
 
175
        p = nullptr;
 
176
    }
 
177
    return p;
 
178
    if (alignment%512==0) {
 
179
        void *raw_ptr;
 
180
        int r = posix_memalign(&raw_ptr, alignment, size);
 
181
        if (r != 0) {
 
182
            errno = r;
 
183
            return nullptr;
 
184
        }
 
185
        push_to_malloced_memory(raw_ptr, raw_ptr, size);
 
186
        return raw_ptr;
 
187
    } else {
 
188
        // Make sure it isn't 512-byte aligned
 
189
        void *raw_ptr;
 
190
        int r = posix_memalign(&raw_ptr, alignment, size+alignment);
 
191
        if (r != 0) {
 
192
            errno = r;
 
193
            return nullptr;
 
194
        }
 
195
        size_t raw_ptr_i = (size_t) raw_ptr;
 
196
        if (raw_ptr_i%512==0) {
 
197
            push_to_malloced_memory(alignment+(char*)raw_ptr, raw_ptr, size);
 
198
            return alignment+(char*)raw_ptr;
 
199
        } else {
 
200
            push_to_malloced_memory(raw_ptr,    raw_ptr, size);
 
201
            return raw_ptr;
 
202
        }
 
203
    }
 
204
}
 
205
 
 
206
static size_t min(size_t a, size_t b) {
 
207
    if (a<b) return a;
 
208
    else return b;
 
209
}
 
210
 
 
211
void *os_realloc(void *p, size_t size) {
 
212
    size_t alignment;
 
213
    if (size<4) {
 
214
        alignment = 1;
 
215
    } else if (size<8) {
 
216
        alignment = 4;
 
217
    } else if (size<16) {
 
218
        alignment = 8;
 
219
    } else {
 
220
        alignment = 16;
 
221
    }
 
222
    return os_realloc_aligned(alignment, p, size);
 
223
}
 
224
 
 
225
void * os_realloc_aligned(size_t alignment, void *p, size_t size)
 
226
// Effect: Perform a realloc(p, size) with the additional property that the returned pointer is a multiple of ALIGNMENT.
 
227
// Requires: alignment is a power of two.
 
228
{
 
229
    if (p==NULL) {
 
230
        return os_malloc_aligned(alignment, size);
 
231
    } else {
 
232
        void *result = os_malloc_aligned(alignment, size);
 
233
        malloc_lock();
 
234
        struct malloc_pair *mp = find_malloced_pair(p);
 
235
        assert(mp);
 
236
        // now copy all the good stuff from p to result
 
237
        memcpy(result, p, min(size, mp->requested_size));
 
238
        malloc_unlock();
 
239
        os_free(p);
 
240
        return result;
 
241
    }
 
242
}
 
243
 
 
244
 
 
245
void os_free(void* p) {
 
246
    malloc_lock();
 
247
    struct malloc_pair *mp = find_malloced_pair(p);
 
248
    assert(mp);
 
249
    free(mp->true_pointer);
 
250
    *mp = malloced_now[--malloced_now_count];
 
251
    malloc_unlock();
 
252
}
 
253
 
 
254
size_t os_malloc_usable_size(const void *p) {
 
255
    malloc_lock();
 
256
    struct malloc_pair *mp = find_malloced_pair(p);
 
257
    assert(mp);
 
258
    size_t size = mp->requested_size;
 
259
    malloc_unlock();
 
260
    return size;
 
261
}
 
262
 
 
263
#else
 
264
 
 
265
void *
 
266
os_malloc(size_t size)
 
267
{
 
268
    return malloc(size);
 
269
}
 
270
 
 
271
void *os_malloc_aligned(size_t alignment, size_t size)
 
272
// Effect: Perform a malloc(size) with the additional property that the returned pointer is a multiple of ALIGNMENT.
 
273
// Requires: alignment is a power of two.
 
274
{
 
275
    void *p;
 
276
    int r = posix_memalign(&p, alignment, size);
 
277
    if (r != 0) {
 
278
        errno = r;
 
279
        p = nullptr;
 
280
    }
 
281
    return p;
 
282
}
 
283
 
 
284
void *
 
285
os_realloc(void *p, size_t size)
 
286
{
 
287
    return realloc(p, size);
 
288
}
 
289
 
 
290
void * os_realloc_aligned(size_t alignment, void *p, size_t size)
 
291
// Effect: Perform a realloc(p, size) with the additional property that the returned pointer is a multiple of ALIGNMENT.
 
292
// Requires: alignment is a power of two.
 
293
{
 
294
#if 1
 
295
    if (p==NULL) {
 
296
        return os_malloc_aligned(alignment, size);
 
297
    } else {
 
298
        void *newp = realloc(p, size);
 
299
        if (0!=((long long)newp%alignment)) {
 
300
            // it's not aligned, so align it ourselves.
 
301
            void *newp2 = os_malloc_aligned(alignment, size);
 
302
            memcpy(newp2, newp, size);
 
303
            free(newp);
 
304
            newp = newp2;
 
305
        }
 
306
        return newp;
 
307
    }
 
308
#else
 
309
    // THIS STUFF SEEMS TO FAIL VALGRIND
 
310
    if (p==NULL) {
 
311
        return os_malloc_aligned(alignment, size);
 
312
    } else {
 
313
        size_t ignore;
 
314
        int r = rallocm(&p,        // returned pointer
 
315
                        &ignore,   // actual size of returned object.
 
316
                        size,      // the size we want
 
317
                        0,         // extra bytes to "try" to allocate at the end
 
318
                        ALLOCM_ALIGN(alignment));
 
319
        if (r!=0) return NULL;
 
320
        else return p;
 
321
    }
 
322
#endif
 
323
}
 
324
 
 
325
 
 
326
void
 
327
os_free(void* p)
 
328
{
 
329
    free(p);
 
330
}
 
331
 
 
332
typedef size_t (*malloc_usable_size_fun_t)(const void *);
 
333
static malloc_usable_size_fun_t malloc_usable_size_f = NULL;
 
334
 
 
335
size_t os_malloc_usable_size(const void *p) {
 
336
    if (p==NULL) return 0;
 
337
    if (!malloc_usable_size_f) {
 
338
        malloc_usable_size_f = (malloc_usable_size_fun_t) dlsym(RTLD_DEFAULT, "malloc_usable_size");
 
339
        if (!malloc_usable_size_f) {
 
340
            malloc_usable_size_f = (malloc_usable_size_fun_t) dlsym(RTLD_DEFAULT, "malloc_size"); // darwin
 
341
            if (!malloc_usable_size_f) {
 
342
                abort(); // couldn't find a malloc size function
 
343
            }
 
344
        }
 
345
    }
 
346
    return malloc_usable_size_f(p);
 
347
}
 
348
#endif