Message ID | 1577c20a41fd09549b8dc3ee933d48bdc668553d.1559819859.git.lucien.xin@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | teamd: fix a json object memleak in get_port_obj() | expand |
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!
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;
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(-)