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