How to handle potential for double frees on errors

42 views
Skip to first unread message

Albert Chu

unread,
Mar 6, 2020, 1:13:45 PM3/6/20
to Jansson users
For a long time we have been programming code like this whenever we have used a "set_new" function in jansson.

----
if (json_object_set_new (o, "foo", val) < 0) {
   json_decref (val);
   json_decref (o);
   return -1;
}
// do stuff
json_decref (o);
----

One developer looked at the code for `json_object_set_new()` and found that `json_decref (val)` is called within the function on errors.  So the above would cause a double free on `val` in the event there's an error.

We usually assume no side effects on failure, so this was a surprise to us. (Side note: perhaps documentation could updated to mention the call to `json_decref()` on error).  This isn't the end of the world, we can adjust code.

However, we are having trouble parsing how to handle this with `json_pack()` usage, e.g.

---
if (!(o = json_pack ("{ s:o }", "foo", val))) {
   json_decref (val);
   return -1;
}
// do stuff
json_decref (o);
---

Some casual glancing at `json_pack()` code suggested that `val` could be `json_decref()`-ed, on certain error paths (I was looking in `pack_object()`) but I haven't been able to reproduce a double free under valgrind.  For example, I thought the following would cause a double free:

---
if (!(o = json_pack ("{ s:o s:o }", "foo", NULL, "bar", val))) {
   json_decref (val);
   return -1;
}
---

but valgrind did not see the double free.

Looking for guidance on how to avoid potential double frees in this case.
Reply all
Reply to author
Forward
0 new messages