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