Coverage Report

Created: 2026-01-09 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dovecot/src/lib/malloc-overflow.h
Line
Count
Source
1
#ifndef MALLOC_OVERFLOW_H
2
#define MALLOC_OVERFLOW_H
3
4
/* MALLOC_*() can be used to calculate memory allocation sizes. If there's an
5
   overflow, it'll cleanly panic instead of causing a potential buffer
6
   overflow.
7
8
   Note that *_malloc(size+1) doesn't need to use MALLOC_ADD(size, 1). It wraps
9
   to size==0 and the *_malloc() calls already panic if size==0. */
10
static inline size_t
11
malloc_multiply_check(size_t a, size_t b, size_t sizeof_a, size_t sizeof_b,
12
          const char *fname, unsigned int linenum)
13
7.21M
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
7.21M
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
7.21M
  return a * b;
22
7.21M
}
Unexecuted instantiation: fuzz-message-decoder.c:malloc_multiply_check
message-decoder.c:malloc_multiply_check
Line
Count
Source
13
8.55k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
8.55k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
8.55k
  return a * b;
22
8.55k
}
Unexecuted instantiation: message-header-decode.c:malloc_multiply_check
message-parser.c:malloc_multiply_check
Line
Count
Source
13
325k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
325k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
325k
  return a * b;
22
325k
}
Unexecuted instantiation: message-size.c:malloc_multiply_check
qp-decoder.c:malloc_multiply_check
Line
Count
Source
13
565
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
565
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
565
  return a * b;
22
565
}
Unexecuted instantiation: quoted-printable.c:malloc_multiply_check
Unexecuted instantiation: rfc2231-parser.c:malloc_multiply_check
Unexecuted instantiation: rfc822-parser.c:malloc_multiply_check
message-header-parser.c:malloc_multiply_check
Line
Count
Source
13
301k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
301k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
301k
  return a * b;
22
301k
}
Unexecuted instantiation: charset-utf8.c:malloc_multiply_check
charset-iconv.c:malloc_multiply_check
Line
Count
Source
13
321k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
321k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
321k
  return a * b;
22
321k
}
Unexecuted instantiation: fuzzer.c:malloc_multiply_check
test-istream.c:malloc_multiply_check
Line
Count
Source
13
8.55k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
8.55k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
8.55k
  return a * b;
22
8.55k
}
Unexecuted instantiation: array.c:malloc_multiply_check
Unexecuted instantiation: base64.c:malloc_multiply_check
buffer.c:malloc_multiply_check
Line
Count
Source
13
3.39M
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
3.39M
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
3.39M
  return a * b;
22
3.39M
}
Unexecuted instantiation: data-stack.c:malloc_multiply_check
Unexecuted instantiation: event-log.c:malloc_multiply_check
Unexecuted instantiation: failures.c:malloc_multiply_check
Unexecuted instantiation: fd-util.c:malloc_multiply_check
Unexecuted instantiation: hex-binary.c:malloc_multiply_check
Unexecuted instantiation: hostpid.c:malloc_multiply_check
Unexecuted instantiation: imem.c:malloc_multiply_check
Unexecuted instantiation: iostream-pump.c:malloc_multiply_check
istream.c:malloc_multiply_check
Line
Count
Source
13
37.2k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
37.2k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
37.2k
  return a * b;
22
37.2k
}
Unexecuted instantiation: istream-data.c:malloc_multiply_check
Unexecuted instantiation: ioloop.c:malloc_multiply_check
Unexecuted instantiation: ioloop-notify-inotify.c:malloc_multiply_check
Unexecuted instantiation: ioloop-epoll.c:malloc_multiply_check
Unexecuted instantiation: lib.c:malloc_multiply_check
lib-event.c:malloc_multiply_check
Line
Count
Source
13
1
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
1
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
1
  return a * b;
22
1
}
Unexecuted instantiation: lib-signals.c:malloc_multiply_check
memarea.c:malloc_multiply_check
Line
Count
Source
13
46.7k
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
46.7k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
46.7k
  return a * b;
22
46.7k
}
Unexecuted instantiation: mempool.c:malloc_multiply_check
mempool-alloconly.c:malloc_multiply_check
Line
Count
Source
13
1
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
1
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
1
  return a * b;
22
1
}
mempool-datastack.c:malloc_multiply_check
Line
Count
Source
13
2.76M
{
14
  /* the first sizeof-checks are intended to optimize away this entire
15
     if-check for types that are small enough to never wrap size_t. */
16
2.76M
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
0
      b != 0 && (a > SIZE_MAX / b)) {
18
0
    i_panic("file %s: line %d: memory allocation overflow: %zu * %zu",
19
0
      fname, linenum, a, b);
20
0
  }
21
2.76M
  return a * b;
22
2.76M
}
Unexecuted instantiation: mempool-system.c:malloc_multiply_check
Unexecuted instantiation: mempool-unsafe-datastack.c:malloc_multiply_check
Unexecuted instantiation: net.c:malloc_multiply_check
Unexecuted instantiation: ostream.c:malloc_multiply_check
Unexecuted instantiation: ostream-file.c:malloc_multiply_check
Unexecuted instantiation: path-util.c:malloc_multiply_check
Unexecuted instantiation: printf-format-fix.c:malloc_multiply_check
Unexecuted instantiation: process-title.c:malloc_multiply_check
Unexecuted instantiation: priorityq.c:malloc_multiply_check
Unexecuted instantiation: punycode.c:malloc_multiply_check
Unexecuted instantiation: randgen.c:malloc_multiply_check
Unexecuted instantiation: rand.c:malloc_multiply_check
Unexecuted instantiation: restrict-access.c:malloc_multiply_check
Unexecuted instantiation: safe-memset.c:malloc_multiply_check
Unexecuted instantiation: sendfile-util.c:malloc_multiply_check
Unexecuted instantiation: sleep.c:malloc_multiply_check
Unexecuted instantiation: str.c:malloc_multiply_check
Unexecuted instantiation: strescape.c:malloc_multiply_check
Unexecuted instantiation: strfuncs.c:malloc_multiply_check
Unexecuted instantiation: strnum.c:malloc_multiply_check
Unexecuted instantiation: time-util.c:malloc_multiply_check
Unexecuted instantiation: unichar.c:malloc_multiply_check
Unexecuted instantiation: unicode-break.c:malloc_multiply_check
Unexecuted instantiation: unicode-data-tables.c:malloc_multiply_check
Unexecuted instantiation: unicode-transform.c:malloc_multiply_check
Unexecuted instantiation: write-full.c:malloc_multiply_check
Unexecuted instantiation: backtrace-string.c:malloc_multiply_check
Unexecuted instantiation: bits.c:malloc_multiply_check
Unexecuted instantiation: env-util.c:malloc_multiply_check
Unexecuted instantiation: event-filter.c:malloc_multiply_check
Unexecuted instantiation: event-filter-lexer.c:malloc_multiply_check
Unexecuted instantiation: event-filter-parser.c:malloc_multiply_check
Unexecuted instantiation: hash.c:malloc_multiply_check
Unexecuted instantiation: ipwd.c:malloc_multiply_check
Unexecuted instantiation: iostream.c:malloc_multiply_check
Unexecuted instantiation: istream-file.c:malloc_multiply_check
Unexecuted instantiation: ioloop-iolist.c:malloc_multiply_check
Unexecuted instantiation: ioloop-notify-fd.c:malloc_multiply_check
Unexecuted instantiation: primes.c:malloc_multiply_check
Unexecuted instantiation: str-parse.c:malloc_multiply_check
Unexecuted instantiation: wildcard-match.c:malloc_multiply_check
23
#ifndef STATIC_CHECKER
24
#  define MALLOC_MULTIPLY(a, b) \
25
7.21M
  malloc_multiply_check(a, b, sizeof(a), sizeof(b), __FILE__, __LINE__) // NOLINT(bugprone-sizeof-expression)
26
#else
27
/* avoid warning every time about sizeof(b) when b contains any arithmetic */
28
#  define MALLOC_MULTIPLY(a, b) \
29
  malloc_multiply_check(a, b, sizeof(a), sizeof(size_t), __FILE__, __LINE__)  // NOLINT(bugprone-sizeof-expression)
30
#endif
31
32
static inline size_t
33
malloc_add_check(size_t a, size_t b, size_t sizeof_a, size_t sizeof_b,
34
     const char *fname, unsigned int linenum)
35
12
{
36
  /* the first sizeof-checks are intended to optimize away this entire
37
     if-check for types that are small enough to never wrap size_t. */
38
12
  if ((sizeof_a >= sizeof(size_t) || sizeof_b >= sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
39
12
      SIZE_MAX - a < b) {
40
0
    i_panic("file %s: line %d: memory allocation overflow: %zu + %zu",
41
0
      fname, linenum, a, b);
42
0
  }
43
12
  return a + b;
44
12
}
Unexecuted instantiation: fuzz-message-decoder.c:malloc_add_check
Unexecuted instantiation: message-decoder.c:malloc_add_check
Unexecuted instantiation: message-header-decode.c:malloc_add_check
Unexecuted instantiation: message-parser.c:malloc_add_check
Unexecuted instantiation: message-size.c:malloc_add_check
Unexecuted instantiation: qp-decoder.c:malloc_add_check
Unexecuted instantiation: quoted-printable.c:malloc_add_check
Unexecuted instantiation: rfc2231-parser.c:malloc_add_check
Unexecuted instantiation: rfc822-parser.c:malloc_add_check
Unexecuted instantiation: message-header-parser.c:malloc_add_check
Unexecuted instantiation: charset-utf8.c:malloc_add_check
Unexecuted instantiation: charset-iconv.c:malloc_add_check
Unexecuted instantiation: fuzzer.c:malloc_add_check
Unexecuted instantiation: test-istream.c:malloc_add_check
Unexecuted instantiation: array.c:malloc_add_check
Unexecuted instantiation: base64.c:malloc_add_check
Unexecuted instantiation: buffer.c:malloc_add_check
data-stack.c:malloc_add_check
Line
Count
Source
35
12
{
36
  /* the first sizeof-checks are intended to optimize away this entire
37
     if-check for types that are small enough to never wrap size_t. */
38
12
  if ((sizeof_a >= sizeof(size_t) || sizeof_b >= sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
39
12
      SIZE_MAX - a < b) {
40
0
    i_panic("file %s: line %d: memory allocation overflow: %zu + %zu",
41
0
      fname, linenum, a, b);
42
0
  }
43
12
  return a + b;
44
12
}
Unexecuted instantiation: event-log.c:malloc_add_check
Unexecuted instantiation: failures.c:malloc_add_check
Unexecuted instantiation: fd-util.c:malloc_add_check
Unexecuted instantiation: hex-binary.c:malloc_add_check
Unexecuted instantiation: hostpid.c:malloc_add_check
Unexecuted instantiation: imem.c:malloc_add_check
Unexecuted instantiation: iostream-pump.c:malloc_add_check
Unexecuted instantiation: istream.c:malloc_add_check
Unexecuted instantiation: istream-data.c:malloc_add_check
Unexecuted instantiation: ioloop.c:malloc_add_check
Unexecuted instantiation: ioloop-notify-inotify.c:malloc_add_check
Unexecuted instantiation: ioloop-epoll.c:malloc_add_check
Unexecuted instantiation: lib.c:malloc_add_check
Unexecuted instantiation: lib-event.c:malloc_add_check
Unexecuted instantiation: lib-signals.c:malloc_add_check
Unexecuted instantiation: memarea.c:malloc_add_check
Unexecuted instantiation: mempool.c:malloc_add_check
Unexecuted instantiation: mempool-alloconly.c:malloc_add_check
Unexecuted instantiation: mempool-datastack.c:malloc_add_check
Unexecuted instantiation: mempool-system.c:malloc_add_check
Unexecuted instantiation: mempool-unsafe-datastack.c:malloc_add_check
Unexecuted instantiation: net.c:malloc_add_check
Unexecuted instantiation: ostream.c:malloc_add_check
Unexecuted instantiation: ostream-file.c:malloc_add_check
Unexecuted instantiation: path-util.c:malloc_add_check
Unexecuted instantiation: printf-format-fix.c:malloc_add_check
Unexecuted instantiation: process-title.c:malloc_add_check
Unexecuted instantiation: priorityq.c:malloc_add_check
Unexecuted instantiation: punycode.c:malloc_add_check
Unexecuted instantiation: randgen.c:malloc_add_check
Unexecuted instantiation: rand.c:malloc_add_check
Unexecuted instantiation: restrict-access.c:malloc_add_check
Unexecuted instantiation: safe-memset.c:malloc_add_check
Unexecuted instantiation: sendfile-util.c:malloc_add_check
Unexecuted instantiation: sleep.c:malloc_add_check
Unexecuted instantiation: str.c:malloc_add_check
Unexecuted instantiation: strescape.c:malloc_add_check
Unexecuted instantiation: strfuncs.c:malloc_add_check
Unexecuted instantiation: strnum.c:malloc_add_check
Unexecuted instantiation: time-util.c:malloc_add_check
Unexecuted instantiation: unichar.c:malloc_add_check
Unexecuted instantiation: unicode-break.c:malloc_add_check
Unexecuted instantiation: unicode-data-tables.c:malloc_add_check
Unexecuted instantiation: unicode-transform.c:malloc_add_check
Unexecuted instantiation: write-full.c:malloc_add_check
Unexecuted instantiation: backtrace-string.c:malloc_add_check
Unexecuted instantiation: bits.c:malloc_add_check
Unexecuted instantiation: env-util.c:malloc_add_check
Unexecuted instantiation: event-filter.c:malloc_add_check
Unexecuted instantiation: event-filter-lexer.c:malloc_add_check
Unexecuted instantiation: event-filter-parser.c:malloc_add_check
Unexecuted instantiation: hash.c:malloc_add_check
Unexecuted instantiation: ipwd.c:malloc_add_check
Unexecuted instantiation: iostream.c:malloc_add_check
Unexecuted instantiation: istream-file.c:malloc_add_check
Unexecuted instantiation: ioloop-iolist.c:malloc_add_check
Unexecuted instantiation: ioloop-notify-fd.c:malloc_add_check
Unexecuted instantiation: primes.c:malloc_add_check
Unexecuted instantiation: str-parse.c:malloc_add_check
Unexecuted instantiation: wildcard-match.c:malloc_add_check
45
#ifndef STATIC_CHECKER
46
#  define MALLOC_ADD(a, b) \
47
12
  malloc_add_check(a, b, sizeof(a), sizeof(b), __FILE__, __LINE__) // NOLINT(bugprone-sizeof-expression)
48
#else
49
/* avoid warning every time about sizeof(b) when b contains any arithmetic */
50
#  define MALLOC_ADD(a, b) \
51
  malloc_add_check(a, b, sizeof(a), sizeof(size_t), __FILE__, __LINE__) // NOLINT(bugprone-sizeof-expression)
52
#endif
53
54
#endif