teamd: fix a json object memleak in get_port_obj()
diff mbox series

Message ID 1577c20a41fd09549b8dc3ee933d48bdc668553d.1559819859.git.lucien.xin@gmail.com
State New
Headers show
Series
  • teamd: fix a json object memleak in get_port_obj()
Related show

Commit Message

Xin Long June 6, 2019, 11:17 a.m. UTC
The issue can be noticed simply by doing:

  # ip link add aeth0 type dummy
  # teamd -d -t ateam0 -c '{"link_watch" : {"name" : "ethtool"}}'
  # teamdctl ateam0 port add aeth0

  # while true; do
  #     teamdctl ateam0 config dump actual > /dev/null
  #     date "+%Y-%m-%dT%H:%M:%S $(ps -auwwx | grep teamd |grep -v grep)"
  # done

After 30 mins:
                      USER       PID %CPU %MEM    VSZ  ... COMMAND
  2019-06-06T06:25:55 root     26574  0.0  0.0  66572  ... teamd ...
  ...
  2019-06-06T06:55:55 root     26574  1.2  0.6  89012  ... teamd ...

MEM used by team grew from 0.0% to 0.6%, VSZ from 66572 to 89012.

get_port_obj() calld in teamd_config_actual_dump() should not have used
json_object_set(), which can json_incref the child object causing later
json_decref(parent object) not to be able to free it.

So change to use json_object_set_new(), a function for setting newly
created objects, and it won't json_incref the child object that will
be freed when its parent object gets freed later.

Fixes: c6eba4866e18 ("teamd: add possibility to add/change port config")
Reported-by: Michael Colombo <mcolombo@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 teamd/teamd_config.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Jiri Pirko July 2, 2019, 10:01 a.m. UTC | #1
Thu, Jun 06, 2019 at 01:17:39PM CEST, lucien.xin@gmail.com wrote:
>The issue can be noticed simply by doing:
>
>  # ip link add aeth0 type dummy
>  # teamd -d -t ateam0 -c '{"link_watch" : {"name" : "ethtool"}}'
>  # teamdctl ateam0 port add aeth0
>
>  # while true; do
>  #     teamdctl ateam0 config dump actual > /dev/null
>  #     date "+%Y-%m-%dT%H:%M:%S $(ps -auwwx | grep teamd |grep -v grep)"
>  # done
>
>After 30 mins:
>                      USER       PID %CPU %MEM    VSZ  ... COMMAND
>  2019-06-06T06:25:55 root     26574  0.0  0.0  66572  ... teamd ...
>  ...
>  2019-06-06T06:55:55 root     26574  1.2  0.6  89012  ... teamd ...
>
>MEM used by team grew from 0.0% to 0.6%, VSZ from 66572 to 89012.
>
>get_port_obj() calld in teamd_config_actual_dump() should not have used
>json_object_set(), which can json_incref the child object causing later
>json_decref(parent object) not to be able to free it.
>
>So change to use json_object_set_new(), a function for setting newly
>created objects, and it won't json_incref the child object that will
>be freed when its parent object gets freed later.
>
>Fixes: c6eba4866e18 ("teamd: add possibility to add/change port config")
>Reported-by: Michael Colombo <mcolombo@redhat.com>
>Signed-off-by: Xin Long <lucien.xin@gmail.com>

applied, thanks!

Patch
diff mbox series

diff --git a/teamd/teamd_config.c b/teamd/teamd_config.c
index 69b25de..34fef1f 100644
--- a/teamd/teamd_config.c
+++ b/teamd/teamd_config.c
@@ -84,7 +84,7 @@  static int get_port_obj(json_t **pport_obj, json_t *config_json,
 		ports_obj = json_object();
 		if (!ports_obj)
 			return -ENOMEM;
-		err = json_object_set(config_json, "ports", ports_obj);
+		err = json_object_set_new(config_json, "ports", ports_obj);
 		if (err) {
 			json_decref(ports_obj);
 			return -ENOMEM;
@@ -95,7 +95,7 @@  static int get_port_obj(json_t **pport_obj, json_t *config_json,
 		port_obj = json_object();
 		if (!port_obj)
 			return -ENOMEM;
-		err = json_object_set(ports_obj, port_name, port_obj);
+		err = json_object_set_new(ports_obj, port_name, port_obj);
 		if (err) {
 			json_decref(port_obj);
 			return -ENOMEM;