Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44be00f7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: qualcomm: rmnet: check for over-pulling"

parents 121ccc2b 912b7c99
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -69,9 +69,11 @@ void rmnet_recycle_frag_descriptor(struct rmnet_frag_descriptor *frag_desc,
				   struct rmnet_port *port)
{
	struct rmnet_frag_descriptor_pool *pool = port->frag_desc_pool;
	struct page *page = skb_frag_page(&frag_desc->frag);

	list_del(&frag_desc->list);
	put_page(skb_frag_page(&frag_desc->frag));
	if (page)
		put_page(page);

	memset(frag_desc, 0, sizeof(*frag_desc));
	INIT_LIST_HEAD(&frag_desc->list);
@@ -457,8 +459,12 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc,
		/* If the headers we added are the start of the page,
		 * we don't want to add them twice
		 */
		if (frag_desc->hdr_ptr == rmnet_frag_data_ptr(frag_desc))
			rmnet_frag_pull(frag_desc, port, hdr_len);
		if (frag_desc->hdr_ptr == rmnet_frag_data_ptr(frag_desc)) {
			if (!rmnet_frag_pull(frag_desc, port, hdr_len)) {
				kfree_skb(head_skb);
				return NULL;
			}
		}
	} else {
		/* Allocate enough space to avoid penalties in the stack
		 * from __pskb_pull_tail()
@@ -645,10 +651,13 @@ rmnet_frag_segment_coal_data(struct rmnet_frag_descriptor *coal_desc,
	bool gro = coal_desc->dev->features & NETIF_F_GRO_HW;

	/* Pull off the headers we no longer need */
	rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header));
	if (!rmnet_frag_pull(coal_desc, port, sizeof(struct rmnet_map_header)))
		return;

	coal_hdr = (struct rmnet_map_v5_coal_header *)
		   rmnet_frag_data_ptr(coal_desc);
	rmnet_frag_pull(coal_desc, port, sizeof(*coal_hdr));
	if (!rmnet_frag_pull(coal_desc, port, sizeof(*coal_hdr)))
		return;

	iph = (struct iphdr *)rmnet_frag_data_ptr(coal_desc);

@@ -897,15 +906,23 @@ int rmnet_frag_process_next_hdr_packet(struct rmnet_frag_descriptor *frag_desc,
			priv->stats.csum_valid_unset++;
		}

		rmnet_frag_pull(frag_desc, port,
		if (!rmnet_frag_pull(frag_desc, port,
				     sizeof(struct rmnet_map_header) +
				sizeof(struct rmnet_map_v5_csum_header));
				     sizeof(struct rmnet_map_v5_csum_header))) {
			rc = -EINVAL;
			break;
		}

		frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc);

		/* Remove padding only for csum offload packets.
		 * Coalesced packets should never have padding.
		 */
		rmnet_frag_trim(frag_desc, port, len);
		if (!rmnet_frag_trim(frag_desc, port, len)) {
			rc = -EINVAL;
			break;
		}

		list_del_init(&frag_desc->list);
		list_add_tail(&frag_desc->list, list);
		break;
@@ -969,10 +986,14 @@ __rmnet_frag_ingress_handler(struct rmnet_frag_descriptor *frag_desc,
			goto recycle;
	} else {
		/* We only have the main QMAP header to worry about */
		rmnet_frag_pull(frag_desc, port, sizeof(*qmap));
		if (!rmnet_frag_pull(frag_desc, port, sizeof(*qmap)))
			return;

		frag_desc->hdr_ptr = rmnet_frag_data_ptr(frag_desc);

		rmnet_frag_trim(frag_desc, port, len);
		if (!rmnet_frag_trim(frag_desc, port, len))
			return;

		list_add_tail(&frag_desc->list, &segs);
	}

+4 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ static inline void *rmnet_frag_pull(struct rmnet_frag_descriptor *frag_desc,
				    unsigned int size)
{
	if (size >= skb_frag_size(&frag_desc->frag)) {
		pr_info("%s(): Pulling %u bytes from %u byte pkt. Dropping\n",
			__func__, size, skb_frag_size(&frag_desc->frag));
		rmnet_recycle_frag_descriptor(frag_desc, port);
		return NULL;
	}
@@ -107,6 +109,8 @@ static inline void *rmnet_frag_trim(struct rmnet_frag_descriptor *frag_desc,
				    unsigned int size)
{
	if (!size) {
		pr_info("%s(): Trimming %u byte pkt to 0. Dropping\n",
			__func__, skb_frag_size(&frag_desc->frag));
		rmnet_recycle_frag_descriptor(frag_desc, port);
		return NULL;
	}