Skip to content

Commit

Permalink
net: hsr: check for return value of skb_put_padto()
Browse files Browse the repository at this point in the history
commit 7dd020835e308be7565d67d4eaa2570915b3774b from
git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git

Currently at couple of places, return value of skb_put_padto() is not
checked. This can cause problem as skb_put_padto() would free skb on
error. So add a check for return value and handle the code properly
when skb is de-allocated.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Xulin Sun <xulin.sun@windriver.com>
  • Loading branch information
Murali Karicheri authored and xulinsun committed Dec 1, 2020
1 parent 537d3e5 commit a05a8a2
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions net/hsr/hsr_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,22 @@ static void prp_set_lan_id(struct prp_rct *trailer, struct hsr_port *port)
}

/* Tailroom for PRP rct should have been created before calling this */
static void prp_fill_rct(struct sk_buff *skb, struct hsr_frame_info *frame,
struct hsr_port *port)
static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
struct hsr_frame_info *frame,
struct hsr_port *port)
{
struct prp_rct *trailer;
int min_size = ETH_ZLEN;
int lsdu_size;

if (!skb)
return;
return skb;

if (frame->is_vlan)
skb_put_padto(skb, VLAN_ETH_ZLEN);
else
skb_put_padto(skb, ETH_ZLEN);
min_size = VLAN_ETH_ZLEN;

if (skb_put_padto(skb, min_size))
return NULL;

trailer = (struct prp_rct *)skb_put(skb, HSR_HLEN);
lsdu_size = skb->len - 14;
Expand All @@ -253,6 +256,8 @@ static void prp_fill_rct(struct sk_buff *skb, struct hsr_frame_info *frame,
set_prp_LSDU_size(trailer, lsdu_size);
trailer->sequence_nr = htons(frame->sequence_nr);
trailer->PRP_suffix = htons(ETH_P_PRP);

return skb;
}

static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr,
Expand All @@ -268,15 +273,17 @@ static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr,
set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id);
}

static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame,
struct hsr_port *port, u8 proto_version)
static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
struct hsr_frame_info *frame,
struct hsr_port *port, u8 proto_version)
{
struct hsr_ethhdr *hsr_ethhdr;
unsigned char *pc;
int lsdu_size;

/* pad to minimum packet size which is 60 + 6 (HSR tag) */
skb_put_padto(skb, ETH_ZLEN + HSR_HLEN);
if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN))
return NULL;

lsdu_size = skb->len - 14;
if (frame->is_vlan)
Expand Down Expand Up @@ -305,6 +312,8 @@ static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame,
hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
hsr_ethhdr->ethhdr.h_proto = htons(proto_version ?
ETH_P_HSR : ETH_P_PRP);

return skb;
}

static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
Expand All @@ -322,7 +331,7 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
skb = skb_copy_expand(skb_o, skb_headroom(skb_o),
skb_tailroom(skb_o) + HSR_HLEN,
GFP_ATOMIC);
prp_fill_rct(skb, frame, port);
skb = prp_fill_rct(skb, frame, port);
return skb;
} else if ((port->hsr->prot_version == HSR_V1) &&
(port->hsr->hsr_mode == IEC62439_3_HSR_MODE_T)) {
Expand All @@ -347,7 +356,9 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
memmove(dst, src, movelen);
skb_reset_mac_header(skb);

hsr_fill_tag(skb, frame, port, port->hsr->prot_version);
skb = hsr_fill_tag(skb, frame, port, port->hsr->prot_version);
if (!skb)
return NULL;

if (REDINFO_T(skb) == DIRECTED_TX)
return skb;
Expand Down

0 comments on commit a05a8a2

Please sign in to comment.