Coverage Report

Created: 2026-09-14 06:49

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
3.52M
{
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.52M
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
78.0k
      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.52M
  return a * b;
22
3.52M
}
Unexecuted instantiation: fuzz-imap-parser.c:malloc_multiply_check
imap-parser.c:malloc_multiply_check
Line
Count
Source
13
50.3k
{
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
50.3k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
48.1k
      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
50.3k
  return a * b;
22
50.3k
}
Unexecuted instantiation: imap-arg.c:malloc_multiply_check
Unexecuted instantiation: fuzzer.c:malloc_multiply_check
test-istream.c:malloc_multiply_check
Line
Count
Source
13
2.13k
{
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.13k
  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.13k
  return a * b;
22
2.13k
}
buffer.c:malloc_multiply_check
Line
Count
Source
13
37.0k
{
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.0k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
6.41k
      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.0k
  return a * b;
22
37.0k
}
Unexecuted instantiation: data-stack.c:malloc_multiply_check
event-log.c:malloc_multiply_check
Line
Count
Source
13
2.13k
{
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.13k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
2.13k
      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.13k
  return a * b;
22
2.13k
}
Unexecuted instantiation: failures.c:malloc_multiply_check
Unexecuted instantiation: fd-util.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
1.64M
{
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.64M
  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.64M
  return a * b;
22
1.64M
}
Unexecuted instantiation: istream-data.c:malloc_multiply_check
ioloop.c:malloc_multiply_check
Line
Count
Source
13
4.27k
{
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
4.27k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
4.27k
      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
4.27k
  return a * b;
22
4.27k
}
Unexecuted instantiation: ioloop-notify-inotify.c:malloc_multiply_check
Unexecuted instantiation: ioloop-epoll.c:malloc_multiply_check
lib.c:malloc_multiply_check
Line
Count
Source
13
2.13k
{
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.13k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
2.13k
      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.13k
  return a * b;
22
2.13k
}
lib-event.c:malloc_multiply_check
Line
Count
Source
13
14.9k
{
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
14.9k
  if ((sizeof_a * 2 > sizeof(size_t) || sizeof_b * 2 > sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
17
14.9k
      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
14.9k
  return a * b;
22
14.9k
}
Unexecuted instantiation: lib-signals.c:malloc_multiply_check
memarea.c:malloc_multiply_check
Line
Count
Source
13
1.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
1.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
1.76M
  return a * b;
22
1.76M
}
Unexecuted instantiation: mempool.c:malloc_multiply_check
mempool-alloconly.c:malloc_multiply_check
Line
Count
Source
13
2.13k
{
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.13k
  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.13k
  return a * b;
22
2.13k
}
Unexecuted instantiation: mempool-datastack.c:malloc_multiply_check
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: 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: array.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: hmac.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: sha2.c:malloc_multiply_check
Unexecuted instantiation: xxh64.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
3.51M
  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
2.13k
{
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
2.13k
  if ((sizeof_a >= sizeof(size_t) || sizeof_b >= sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
39
2.13k
      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
2.13k
  return a + b;
44
2.13k
}
Unexecuted instantiation: fuzz-imap-parser.c:malloc_add_check
Unexecuted instantiation: imap-parser.c:malloc_add_check
Unexecuted instantiation: imap-arg.c:malloc_add_check
Unexecuted instantiation: fuzzer.c:malloc_add_check
Unexecuted instantiation: test-istream.c:malloc_add_check
Unexecuted instantiation: buffer.c:malloc_add_check
data-stack.c:malloc_add_check
Line
Count
Source
35
2.13k
{
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
2.13k
  if ((sizeof_a >= sizeof(size_t) || sizeof_b >= sizeof(size_t)) && // NOLINT(bugprone-sizeof-expression)
39
2.13k
      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
2.13k
  return a + b;
44
2.13k
}
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: 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: 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: array.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: hmac.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: sha2.c:malloc_add_check
Unexecuted instantiation: xxh64.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
2.13k
  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
/* Minimal convenience wrapper for common allocation size arithmetic.
55
   Built on MALLOC_ADD() to keep overflow handling centralized. */
56
#define MALLOC_ADD3(a, b, c) \
57
0
  MALLOC_ADD(MALLOC_ADD((a), (b)), (c))
58
59
#endif