re: GTP: add support for flow based tunneling API

From: Colin Ian King <hidden>
Date: 2021-01-18 12:06:01
Also in: lkml

Hi,

Static analysis of today's linux-next using Coverity has found a
potential memory leak issue in the following commit:

commit 9ab7e76aefc97a9aa664accb59d6e8dc5e52514a
Author: Pravin B Shelar [off-list ref]
Date:   Sat Jan 9 23:00:21 2021 -0800

    GTP: add support for flow based tunneling API

The analysis is as follows:

186 static int gtp_set_tun_dst(struct gtp_dev *gtp, struct sk_buff *skb,
187                           unsigned int hdrlen, u8 gtp_version,
188                           __be64 tid, u8 flags)
189 {
190        struct metadata_dst *tun_dst;
191        int opts_len = 0;
192

   1. Condition !!(flags & 7), taking true branch.
   2. Condition !!(flags & 7), taking true branch.

193        if (unlikely(flags & GTP1_F_MASK))
194                opts_len = sizeof(struct gtpu_metadata);
195

   3. alloc_fn: Storage is returned from allocation function udp_tun_rx_dst.
   4. var_assign: Assigning: tun_dst = storage returned from
udp_tun_rx_dst(skb, gtp->sk1u->__sk_common.skc_family, 1024, tid, opts_len).

196        tun_dst = udp_tun_rx_dst(skb, gtp->sk1u->sk_family,
TUNNEL_KEY, tid, opts_len);

   5. Condition !tun_dst, taking false branch.

197        if (!tun_dst) {
198                netdev_dbg(gtp->dev, "Failed to allocate tun_dst");
199                goto err;
200        }
201

   6. Condition 0 /* __builtin_types_compatible_p() */, taking false branch.
   7. Condition 1 /* __builtin_types_compatible_p() */, taking true branch.
   8. Falling through to end of if statement.
   9. Condition !!branch, taking false branch.
   10. Condition ({...; !!branch;}), taking false branch.

202        netdev_dbg(gtp->dev, "attaching metadata_dst to skb, gtp ver
%d hdrlen %d\n",
203                   gtp_version, hdrlen);

   11. Condition !!opts_len, taking true branch.
   12. Condition !!opts_len, taking true branch.

204        if (unlikely(opts_len)) {
205                struct gtpu_metadata *opts;
206                struct gtp1_header *gtp1;
207
208                opts = ip_tunnel_info_opts(&tun_dst->u.tun_info);
209                gtp1 = (struct gtp1_header *)(skb->data +
sizeof(struct udphdr));
210                opts->ver = GTP_METADATA_V1;
211                opts->flags = gtp1->flags;
212                opts->type = gtp1->type;

   13. Condition 0 /* __builtin_types_compatible_p() */, taking false
branch.
   14. Condition 1 /* __builtin_types_compatible_p() */, taking true branch.
   15. Falling through to end of if statement.
   16. Condition !!branch, taking false branch.
   17. Condition ({...; !!branch;}), taking false branch.

213                netdev_dbg(gtp->dev, "recved control pkt: flag %x
type: %d\n",
214                           opts->flags, opts->type);
215                tun_dst->u.tun_info.key.tun_flags |= TUNNEL_GTPU_OPT;
216                tun_dst->u.tun_info.options_len = opts_len;
217                skb->protocol = htons(0xffff);         /* Unknown */
218        }
219        /* Get rid of the GTP + UDP headers. */

   18. Condition !net_eq(sock_net(gtp->sk1u), dev_net(gtp->dev)), taking
false branch.
   19. Condition !net_eq(sock_net(gtp->sk1u), dev_net(gtp->dev)), taking
false branch.
   20. Condition iptunnel_pull_header(skb, hdrlen, skb->protocol,
!net_eq(sock_net(gtp->sk1u), dev_net(gtp->dev))), taking true branch.

220        if (iptunnel_pull_header(skb, hdrlen, skb->protocol,
221                                 !net_eq(sock_net(gtp->sk1u),
dev_net(gtp->dev)))) {
222                gtp->dev->stats.rx_length_errors++;

   21. Jumping to label err.

223                goto err;
224        }
225
226        skb_dst_set(skb, &tun_dst->dst);
227        return 0;
228 err:

   Resource leak (RESOURCE_LEAK)
   22. leaked_storage: Variable tun_dst going out of scope leaks the
storage it points to.

229        return -1;
230 }

The goto on line 223 is leaking tun_dst.  From what I can see, I believe
a call to kfree(tun_dst) before the goto on line 223 looks like a
pertinent fix, but I'm not 100% sure, so I'm flagging this up as an
issue that need further investigation by folk who are more familiar with
this code.

Colin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help