923a60
From 164a98ea6b24fea3433516dcc0df496929674cdd Mon Sep 17 00:00:00 2001
923a60
From: Jan Synacek <jsynacek@redhat.com>
923a60
Date: Tue, 7 Jun 2016 12:43:38 +0200
923a60
Subject: [PATCH] sd-netlink: fix deep recursion in message destruction
923a60
923a60
On larger systems we might very well see messages with thousands of parts.
923a60
When we free them, we must avoid recursing into each part, otherwise we
923a60
very likely get stack overflows.
923a60
923a60
Fix sd_netlink_message_unref() to use an iterative approach rather than
923a60
recursion (also avoid tail-recursion in case it is not optimized by the
923a60
compiler).
923a60
923a60
(cherry picked from commit 82e4eda664d40ef60829e27d84b1610c2f4070cd)
923a60
Resolves: #1330593
923a60
---
923a60
 src/libsystemd/sd-rtnl/rtnl-message.c | 10 ++++++----
923a60
 1 file changed, 6 insertions(+), 4 deletions(-)
923a60
923a60
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
923a60
index 276591f31b..9276bbdebc 100644
923a60
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
923a60
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
923a60
@@ -584,7 +584,9 @@ sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
923a60
 }
923a60
 
923a60
 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
923a60
-        if (m && REFCNT_DEC(m->n_ref) == 0) {
923a60
+        sd_rtnl_message *t;
923a60
+
923a60
+        while (m && REFCNT_DEC(m->n_ref) == 0) {
923a60
                 unsigned i;
923a60
 
923a60
                 free(m->hdr);
923a60
@@ -592,9 +594,9 @@ sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
923a60
                 for (i = 0; i <= m->n_containers; i++)
923a60
                         free(m->rta_offset_tb[i]);
923a60
 
923a60
-                sd_rtnl_message_unref(m->next);
923a60
-
923a60
-                free(m);
923a60
+                t = m;
923a60
+                m = m->next;
923a60
+                free(t);
923a60
         }
923a60
 
923a60
         return NULL;