Skip to content

Commit

Permalink
mpls: drop skb's dst in mpls_forward()
Browse files Browse the repository at this point in the history
Commit 394de11 ("net: Added pointer check for
dst->ops->neigh_lookup in dst_neigh_lookup_skb") added a test in
dst_neigh_lookup_skb() to avoid a NULL pointer dereference. The root
cause was the MPLS forwarding code, which doesn't call skb_dst_drop()
on incoming packets. That is, if the packet is received from a
collect_md device, it has a metadata_dst attached to it that doesn't
implement any dst_ops function.

To align the MPLS behaviour with IPv4 and IPv6, let's drop the dst in
mpls_forward(). This way, dst_neigh_lookup_skb() doesn't need to test
->neigh_lookup any more. Let's keep a WARN condition though, to
document the precondition and to ease detection of such problems in the
future.

Signed-off-by: Guillaume Nault <gnault@redhat.com>
Link: https://lore.kernel.org/r/f8c2784c13faa54469a2aac339470b1049ca6b63.1604102750.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Guillaume Nault authored and Jakub Kicinski committed Nov 3, 2020
1 parent 6d89076 commit 0992d67
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 7 deletions.
12 changes: 5 additions & 7 deletions include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,12 @@ static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, co
static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst,
struct sk_buff *skb)
{
struct neighbour *n = NULL;
struct neighbour *n;

/* The packets from tunnel devices (eg bareudp) may have only
* metadata in the dst pointer of skb. Hence a pointer check of
* neigh_lookup is needed.
*/
if (dst->ops->neigh_lookup)
n = dst->ops->neigh_lookup(dst, skb, NULL);
if (WARN_ON_ONCE(!dst->ops->neigh_lookup))
return NULL;

n = dst->ops->neigh_lookup(dst, skb, NULL);

return IS_ERR(n) ? NULL : n;
}
Expand Down
2 changes: 2 additions & 0 deletions net/mpls/af_mpls.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
if (!pskb_may_pull(skb, sizeof(*hdr)))
goto err;

skb_dst_drop(skb);

/* Read and decode the label */
hdr = mpls_hdr(skb);
dec = mpls_entry_decode(hdr);
Expand Down

0 comments on commit 0992d67

Please sign in to comment.