summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-03-09 18:41:19 +0100
committerJo-Philipp Wich <jo@mein.io>2021-03-09 18:45:41 +0100
commit6d0b7a8c38e8283bbe91053cbd650af9a36aa4d4 (patch)
treec7d2475734c2d23479bce86f56e4b3636f6715f1
parent19ce337dc17e5f3b7a2cacd66e139ef5b295223a (diff)
lib: prevent possible use-after-free in uc_pop()
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--lib.c4
-rw-r--r--tests/03_bugs/02_array_pop_use_after_free14
2 files changed, 16 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 536fcd7..54eb710 100644
--- a/lib.c
+++ b/lib.c
@@ -445,14 +445,14 @@ uc_pop(uc_vm *vm, size_t nargs)
arrlen = json_object_array_length(arr);
if (arrlen > 0) {
- item = json_object_array_get_idx(arr, arrlen - 1);
+ item = uc_value_get(json_object_array_get_idx(arr, arrlen - 1));
json_object_array_del_idx(arr, arrlen - 1, 1);
#ifdef HAVE_ARRAY_SHRINK
json_object_array_shrink(arr, 0);
#endif
}
- return uc_value_get(item);
+ return item;
}
static json_object *
diff --git a/tests/03_bugs/02_array_pop_use_after_free b/tests/03_bugs/02_array_pop_use_after_free
new file mode 100644
index 0000000..22f63ff
--- /dev/null
+++ b/tests/03_bugs/02_array_pop_use_after_free
@@ -0,0 +1,14 @@
+When popping an element off an array, especially the last one, the popped
+value might have been freed before the refcount was increased later on
+function return.
+
+-- Expect stdout --
+1
+-- End --
+
+-- Testcase --
+{%
+ x = [1];
+ print(pop(x), "\n"); // This caused a SIGABRT before the bugfix
+%}
+-- End --