From d7547e191fbba858fab1c80d07a1f0e3c1dd05a9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 26 Sep 2019 16:56:36 -0400
Subject: [PATCH 57/61] FIXME: add various demos

---
 demo-control.c                    | 44 +++++++++++++++++++++++++++++++++++++++
 demo-direct-with-loop.c           | 22 ++++++++++++++++++++
 demo-direct.c                     | 31 +++++++++++++++++++++++++++
 demo-indirect.c                   | 21 +++++++++++++++++++
 demo.c                            | 38 +++++++++++++++++++++++++++++++++
 examples/demo.c                   | 30 ++++++++++++++++++++++++++
 examples/lto-double-free/api.c    | 15 +++++++++++++
 examples/lto-double-free/api.h    |  9 ++++++++
 examples/lto-double-free/client.c |  8 +++++++
 test.c                            | 12 +++++++++++
 10 files changed, 230 insertions(+)
 create mode 100644 demo-control.c
 create mode 100644 demo-direct-with-loop.c
 create mode 100644 demo-direct.c
 create mode 100644 demo-indirect.c
 create mode 100644 demo.c
 create mode 100644 examples/demo.c
 create mode 100644 examples/lto-double-free/api.c
 create mode 100644 examples/lto-double-free/api.h
 create mode 100644 examples/lto-double-free/client.c
 create mode 100644 test.c

diff --git a/demo-control.c b/demo-control.c
new file mode 100644
index 0000000..68b8609
--- /dev/null
+++ b/demo-control.c
@@ -0,0 +1,44 @@
+extern void __dump_constraints (void);
+
+void test_cond (int flag)
+{
+  if (flag)
+    __dump_constraints ();
+  else
+    __dump_constraints ();
+}
+
+void test_switch (int x)
+{
+  switch (x)
+    {
+    case 5 ... 10:
+      __dump_constraints ();
+      break;
+
+    case 17:
+      __dump_constraints ();
+      break;
+
+    default:
+      __dump_constraints ();
+      break;
+    }
+}
+
+extern void do_something (int i);
+
+void test_double_diamond (int flag)
+{
+  if (flag)
+    do_something (0);
+  else
+    do_something (1);
+
+  do_something (2);
+
+  if (flag)
+    __dump_constraints ();
+  else
+    __dump_constraints ();
+}
diff --git a/demo-direct-with-loop.c b/demo-direct-with-loop.c
new file mode 100644
index 0000000..446cd7e
--- /dev/null
+++ b/demo-direct-with-loop.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+
+void test (void)
+{
+  void *ptr = malloc (1024);
+
+  int i;
+  for (i = 0; i < 1024; i++)
+    free (ptr); /* BUG: double-free, 2nd time in loop.  */
+}
+
+void test_2 (void)
+{
+  void *ptr = malloc (1024);
+
+  int i;
+  for (i = 0; i < 1024; i++)
+    foo ();
+
+  free (ptr);
+  free (ptr);
+}
diff --git a/demo-direct.c b/demo-direct.c
new file mode 100644
index 0000000..f43de69
--- /dev/null
+++ b/demo-direct.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+
+void test (void)
+{
+  void *ptr = malloc (1024);
+  free (ptr);
+  free (ptr); /* BUG: double-free.  */
+}
+
+void test_2 (int x, int y)
+{
+  void *ptr = malloc (1024);
+  if (x)
+    free (ptr);
+  if (y)
+    free (ptr); /* BUG: double-free.  */
+  /* BUG: leak.  */
+}
+
+int test_3 (int x, int y)
+{
+  int *ptr = (int *)malloc (sizeof (int));
+  *ptr = 42;
+  if (x)
+    free (ptr);
+  *ptr = 19;
+  if (y)
+    free (ptr); /* BUG: double-free.  */
+  return *ptr;
+  /* BUG: leak.  */
+}
diff --git a/demo-indirect.c b/demo-indirect.c
new file mode 100644
index 0000000..cf4dd50
--- /dev/null
+++ b/demo-indirect.c
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+
+void *
+calls_malloc (void)
+{
+  void *result = malloc (1024);
+  return result;
+}
+
+void
+calls_free (void *victim)
+{
+  free (victim);
+}
+
+void test (void)
+{
+  void *ptr = calls_malloc ();
+  calls_free (ptr);
+  calls_free (ptr); /* BUG: double-free.  */
+}
diff --git a/demo.c b/demo.c
new file mode 100644
index 0000000..2572d49
--- /dev/null
+++ b/demo.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void do_stuff (void);
+
+int test (const char *filename, int flag)
+{
+  FILE *f;
+  int *p, *q;
+  int i;
+
+  f = fopen (filename, "w");
+  if (!f)
+    return -1;
+
+  p = (int *)malloc (sizeof (int));
+  if (!p)
+    {
+      free (p);
+      fclose (f);
+      return -1;
+    }
+
+  q = (int *)malloc (sizeof (int));
+  if (!q)
+    {
+      free (p);
+      fclose (f);
+      /* oops: forgot the "return" here, so it falls through.  */
+    }
+
+  do_stuff ();
+
+  free (p);
+  free (q);
+  fclose (f);
+  return 0;
+}
diff --git a/examples/demo.c b/examples/demo.c
new file mode 100644
index 0000000..7e17781
--- /dev/null
+++ b/examples/demo.c
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+
+typedef struct boxed_int
+{
+  int val;
+} boxed_int;
+
+extern boxed_int *make_boxed_int (int i);
+extern void free_boxed_int (boxed_int *victim);
+
+boxed_int *
+make_boxed_int (int val)
+{
+  boxed_int *new_ptr = (boxed_int *)malloc (sizeof (boxed_int));
+  new_ptr->val = val;
+  return new_ptr;
+}
+
+void
+free_boxed_int (boxed_int *victim)
+{
+  free (victim);
+}
+
+void test (int x)
+{
+  boxed_int *bi = make_boxed_int (x);
+  free_boxed_int (bi);
+  free_boxed_int (bi); /* BUG: double-free.  */
+}
diff --git a/examples/lto-double-free/api.c b/examples/lto-double-free/api.c
new file mode 100644
index 0000000..a418ee4
--- /dev/null
+++ b/examples/lto-double-free/api.c
@@ -0,0 +1,15 @@
+#include "api.h"
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *bi = (boxed_int *)malloc (sizeof (boxed_int));
+  bi->i = i;
+  return bi;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  free (bi);
+}
diff --git a/examples/lto-double-free/api.h b/examples/lto-double-free/api.h
new file mode 100644
index 0000000..ebdfa89
--- /dev/null
+++ b/examples/lto-double-free/api.h
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+extern boxed_int *make_boxed_int (int i);
+extern void free_boxed_int (boxed_int *bi);
diff --git a/examples/lto-double-free/client.c b/examples/lto-double-free/client.c
new file mode 100644
index 0000000..4c7e642
--- /dev/null
+++ b/examples/lto-double-free/client.c
@@ -0,0 +1,8 @@
+#include "api.h"
+
+void test (int i)
+{
+  boxed_int *bi = make_boxed_int (i);
+  free_boxed_int (bi);
+  free_boxed_int (bi); /* BUG: double-free.  */
+}
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..da4554c
--- /dev/null
+++ b/test.c
@@ -0,0 +1,12 @@
+void test (int *ptr)
+{
+  if (ptr)
+    *ptr = 42;
+  else
+    *ptr = 43;
+}
+
+int main(int argc, char *argv[]) {
+  *((int*) 0) = 0;
+  return 0;
+}
-- 
1.8.5.3

