File: mem_alloc_utils.h

package info (click to toggle)
openssl 3.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 148,104 kB
  • sloc: ansic: 612,658; perl: 248,939; asm: 6,332; sh: 1,755; pascal: 997; python: 648; makefile: 551; lisp: 35; ruby: 16; cpp: 10; sed: 6
file content (113 lines) | stat: -rw-r--r-- 3,248 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * Utility overflow checking and reporting functions
 */

#ifndef OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H
# define OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H

# include <limits.h>
# include <stdbool.h>
# include <stdint.h>

# include "internal/common.h"
# include "internal/safe_math.h"

# include <openssl/cryptoerr.h>
# include <openssl/err.h>

OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)

/*
 * A helper routine to report memory allocation errors.
 * Similar to the ERR_raise() macro, but accepts explicit file/line arguments,
 * pre-defines the library to ERR_LIB_CRYPTO, and avoids emitting an error
 * if both file set to NULL and line set to 0.
 */
static ossl_inline ossl_unused void
ossl_report_alloc_err_ex(const char * const file, const int line,
                         const int reason)
{
    /*
     * ossl_err_get_state_int() in err.c uses CRYPTO_zalloc(num, NULL, 0) for
     * ERR_STATE allocation. Prevent mem alloc error loop while reporting error.
     */
    if (file != NULL || line != 0) {
        ERR_new();
        ERR_set_debug(file, line, NULL);
        ERR_set_error(ERR_LIB_CRYPTO, reason, NULL);
    }
}

/* Report a memory allocation failure. */
static ossl_inline ossl_unused void
ossl_report_alloc_err(const char * const file, const int line)
{
    ossl_report_alloc_err_ex(file, line, ERR_R_MALLOC_FAILURE);
}

/* Report an integer overflow during allocation size calculation. */
static ossl_inline ossl_unused void
ossl_report_alloc_err_of(const char * const file, const int line)
{
    ossl_report_alloc_err_ex(file, line, CRYPTO_R_INTEGER_OVERFLOW);
}

/* Report invalid memory allocation call arguments. */
static ossl_inline ossl_unused void
ossl_report_alloc_err_inv(const char * const file, const int line)
{
    ossl_report_alloc_err_ex(file, line, ERR_R_PASSED_INVALID_ARGUMENT);
}

/*
 * Check the result of num and size multiplication for overflow
 * and set error if it is the case;  return true if there was no overflow,
 * false if there was.
 */
static ossl_inline ossl_unused bool
ossl_size_mul(const size_t num, const size_t size, size_t *bytes,
              const char * const file, const int line)
{
    int err = 0;
    *bytes = safe_mul_size_t(num, size, &err);

    if (ossl_unlikely(err != 0)) {
        ossl_report_alloc_err_of(file, line);

        return false;
    }

    return true;
}

/*
 * Check the result of size1 and size2 addition for overflow
 * and set error if it is the case;  returns true if there was no overflow,
 * false if there was.
 */
static ossl_inline ossl_unused bool
ossl_size_add(const size_t size1, const size_t size2, size_t *bytes,
              const char * const file, const int line)
{
    int err = 0;
    *bytes = safe_add_size_t(size1, size2, &err);

    if (ossl_unlikely(err != 0)) {
        ossl_report_alloc_err_of(file, line);

        return false;
    }

    return true;
}

#endif /* OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H */