aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c
blob: f8eb1580eb3568ef2d68c554d17e6d52576e677a (plain)
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
/* { dg-additional-options "-fdiagnostics-text-art-charset=unicode" } */
/* { dg-require-effective-target alloca } */

#include <stdlib.h>
#include <stdint.h>
#include <string.h>

void test6 (size_t size)
{
  int32_t *buf = __builtin_alloca (4 * size);
  memset (buf, 0, 4 * size);
  int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */
}

/* (size * 16) - (size * 4) leads to a gap of (size * 12).  */

/* { dg-begin-multiline-output "" }

                                                       ┌─────────────────┐
                                                       │ read of 4 bytes │
                                                       └─────────────────┘
                                                                ^


  ┌────────────────────────────────┐                   ┌─────────────────┐
  │buffer allocated on stack at (1)│                   │after valid range│
  └────────────────────────────────┘                   └─────────────────┘
  ├───────────────┬────────────────┤├────────┬────────┤├────────┬────────┤
                  │                          │                  │
                  │                          │       ╭──────────┴─────────╮
                  │                          │       │over-read of 4 bytes│
                  │                          │       ╰────────────────────╯
      ╭───────────┴──────────╮      ╭────────┴────────╮
      │size: 'size * 4' bytes│      │'size * 12' bytes│
      ╰──────────────────────╯      ╰─────────────────╯

   { dg-end-multiline-output "" } */

void test7 (size_t size)
{
  int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */
  buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */
}

/* { dg-begin-multiline-output "" }

                                 ┌───────────────────────────────────────┐
                                 │          write of '(int) 42'          │
                                 └───────────────────────────────────────┘
                                           │                   │
                                           │                   │
                                           v                   v
  ┌──────────────────────────────────────────────────┐┌──────────────────┐
  │         buffer allocated on stack at (1)         ││after valid range │
  └──────────────────────────────────────────────────┘└──────────────────┘
  ├────────────────────────┬─────────────────────────┤├────────┬─────────┤
                           │                                   │
           ╭───────────────┴──────────────╮          ╭─────────┴────────╮
           │capacity: 'size * 4 + 3' bytes│          │overflow of 1 byte│
           ╰──────────────────────────────╯          ╰──────────────────╯

   { dg-end-multiline-output "" } */


/* We're currently not able to generate a diagram for this case;
   make sure we handle this case gracefully.  */

char *test99 (const char *x, const char *y)
{
  size_t len_x = __builtin_strlen (x);
  size_t len_y = __builtin_strlen (y);
  /* BUG (root cause): forgot to add 1 for terminator.  */
  size_t sz = len_x + len_y;
  char *result = __builtin_malloc (sz);
  if (!result)
    return NULL;
  __builtin_memcpy (result, x, len_x);
  __builtin_memcpy (result + len_x, y, len_y);
  /* BUG (symptom): off-by-one out-of-bounds write to heap.  */
  result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */
  return result;
}