Message ID | 20231115075650.33219-1-heminhong@kylinos.cn (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Stephen Hemminger |
Headers | show |
Series | [v3] iproute2: prevent memory leak | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
heminhong <heminhong@kylinos.cn> writes: > When the return value of rtnl_talk() is greater than > or equal to 0, 'answer' will be allocated. > The 'answer' should be free after using, > otherwise it will cause memory leak. The patch also frees the memory when rtnl_talk() returns < 0. In that case the answer has not been initialized. You should probably initialize the answer to NULL. > Signed-off-by: heminhong <heminhong@kylinos.cn> > --- > ip/link_gre.c | 1 + > ip/link_gre6.c | 1 + > ip/link_ip6tnl.c | 1 + > ip/link_iptnl.c | 1 + > ip/link_vti.c | 1 + > ip/link_vti6.c | 1 + > 6 files changed, 6 insertions(+) > > diff --git a/ip/link_gre.c b/ip/link_gre.c > index 74a5b5e9..3d3fcbae 100644 > --- a/ip/link_gre.c > +++ b/ip/link_gre.c > @@ -113,6 +113,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, > get_failed: > fprintf(stderr, > "Failed to get existing tunnel info.\n"); > + free(answer); > return -1; > } > The context of this hunk is: struct nlmsghdr *answer; ... answer untouched here ... if (rtnl_talk(&rth, &req.n, &answer) < 0) { get_failed: + free(answer); fprintf(stderr, "Failed to get existing tunnel info.\n"); return -1; } If rtnl_talk() fails, answer is never initialized, so passing it to free is invalid.
diff --git a/ip/link_gre.c b/ip/link_gre.c index 74a5b5e9..3d3fcbae 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -113,6 +113,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; } diff --git a/ip/link_gre6.c b/ip/link_gre6.c index b03bd65a..d74472d2 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -115,6 +115,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; } diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index b27d696f..8498b726 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -101,6 +101,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; } diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c index 1315aebe..2ee4011d 100644 --- a/ip/link_iptnl.c +++ b/ip/link_iptnl.c @@ -105,6 +105,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; } diff --git a/ip/link_vti.c b/ip/link_vti.c index 50943254..dbbfcb2b 100644 --- a/ip/link_vti.c +++ b/ip/link_vti.c @@ -69,6 +69,7 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; } diff --git a/ip/link_vti6.c b/ip/link_vti6.c index 5764221e..096759e6 100644 --- a/ip/link_vti6.c +++ b/ip/link_vti6.c @@ -71,6 +71,7 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); + free(answer); return -1; }
When the return value of rtnl_talk() is greater than or equal to 0, 'answer' will be allocated. The 'answer' should be free after using, otherwise it will cause memory leak. Signed-off-by: heminhong <heminhong@kylinos.cn> --- ip/link_gre.c | 1 + ip/link_gre6.c | 1 + ip/link_ip6tnl.c | 1 + ip/link_iptnl.c | 1 + ip/link_vti.c | 1 + ip/link_vti6.c | 1 + 6 files changed, 6 insertions(+)