diff options
author | Thomas Haller <thaller@redhat.com> | 2022-04-22 16:10:01 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-04-22 16:10:01 (GMT) |
commit | 46e85d210282a626c0c19a9c6f2b8696342c1697 (patch) | |
tree | 9fadbab039c8eea05e1c24586faec8be1aa42f34 | |
parent | b0641dd721995ee3c0b0b0acb5917559c566f4b1 (diff) | |
download | libnl-46e85d210282a626c0c19a9c6f2b8696342c1697.zip libnl-46e85d210282a626c0c19a9c6f2b8696342c1697.tar.gz libnl-46e85d210282a626c0c19a9c6f2b8696342c1697.tar.bz2 |
route/mdb: fix leak in mdb_msg_parser()
Found by coverity:
libnl-3.6.0/lib/route/mdb.c:242: leaked_storage: Variable "entry" going out of scope leaks the storage it points to.
-rw-r--r-- | lib/route/mdb.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/lib/route/mdb.c b/lib/route/mdb.c index 39fad48..2bc27bb 100644 --- a/lib/route/mdb.c +++ b/lib/route/mdb.c @@ -176,7 +176,7 @@ static int mdb_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, struct br_port_msg *port; struct nlattr *nla; struct br_mdb_entry *e; - struct rtnl_mdb *mdb = rtnl_mdb_alloc(); + _nl_auto_rtnl_mdb struct rtnl_mdb *mdb = rtnl_mdb_alloc(); if (!mdb) return -NLE_NOMEM; @@ -184,7 +184,7 @@ static int mdb_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, err = nlmsg_parse(nlh, sizeof(struct br_port_msg), tb, MDBA_MAX, mdb_policy); if (err < 0) - goto errout; + return err; mdb->ce_msgtype = nlh->nlmsg_type; @@ -206,51 +206,47 @@ static int mdb_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, for (nla2 = nla_data(nla); nla_ok(nla2, rm); nla2 = nla_next(nla2, &rm)) { - struct rtnl_mdb_entry *entry = rtnl_mdb_entry_alloc(); + _nl_auto_nl_addr struct nl_addr *addr = NULL; + struct rtnl_mdb_entry *entry; + uint16_t proto; + + e = nla_data(nla2); + + proto = ntohs(e->addr.proto); - if (!entry) { - goto errout; + if (proto == ETH_P_IP) { + addr = nl_addr_build( + AF_INET, &e->addr.u.ip4, + sizeof(e->addr.u.ip4)); + } else if (proto == ETH_P_IPV6) { + addr = nl_addr_build( + AF_INET6, &e->addr.u.ip6, + sizeof(e->addr.u.ip6)); + } else { + addr = nl_addr_build( + AF_LLC, e->addr.u.mac_addr, + sizeof(e->addr.u.mac_addr)); } + if (!addr) + return -NLE_NOMEM; - e = nla_data(nla2); + entry = rtnl_mdb_entry_alloc(); + if (!entry) + return -NLE_NOMEM; mdb->ce_mask |= MDB_ATTR_ENTRIES; entry->ifindex = e->ifindex; - entry->vid = e->vid; - entry->state = e->state; - entry->proto = ntohs(e->addr.proto); - - if (entry->proto == ETH_P_IP) { - entry->addr = nl_addr_build(AF_INET, - &e->addr.u.ip4, - sizeof(e->addr.u.ip4)); - } else if (entry->proto == ETH_P_IPV6) { - entry->addr = nl_addr_build(AF_INET6, - &e->addr.u.ip6, - sizeof(e->addr.u.ip6)); - } else { - entry->addr = nl_addr_build(AF_LLC, - e->addr.u.mac_addr, - sizeof(e->addr.u.mac_addr)); - } - - if (!entry->addr) - goto errout; - + entry->addr = _nl_steal_pointer(&addr); rtnl_mdb_add_entry(mdb, entry); } } } - err = pp->pp_cb((struct nl_object *) mdb, pp); -errout: - rtnl_mdb_put(mdb); - - return err; + return pp->pp_cb((struct nl_object *) mdb, pp); } static int mdb_request_update(struct nl_cache *cache, struct nl_sock *sk) |