Unverified Commit 1a79212e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!5491 CVE-2024-26640

Merge Pull Request from: @ci-robot 
 
PR sync from: Ziyang Xuan <william.xuanziyang@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/MUQJDUF6ATJTRSIUQX7JW4PD6W47DXZI/ 
Patchset for CVE-2024-26640.

Arjun Roy (1):
  net-zerocopy: Refactor frag-is-remappable test.

Eric Dumazet (1):
  tcp: add sanity checks to rx zerocopy


-- 
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/I99JO6 
 
Link:https://gitee.com/openeuler/kernel/pulls/5491

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 28ad13bd ce8064b9
Loading
Loading
Loading
Loading
+36 −8
Original line number Diff line number Diff line
@@ -1792,6 +1792,36 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb,
	return frag;
}

static bool can_map_frag(const skb_frag_t *frag)
{
	struct page *page;

	if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag))
		return false;

	page = skb_frag_page(frag);

	if (PageCompound(page) || page->mapping)
		return false;

	return true;
}

static int find_next_mappable_frag(const skb_frag_t *frag,
				   int remaining_in_skb)
{
	int offset = 0;

	if (likely(can_map_frag(frag)))
		return 0;

	while (offset < remaining_in_skb && !can_map_frag(frag)) {
		offset += skb_frag_size(frag);
		++frag;
	}
	return offset;
}

static int tcp_copy_straggler_data(struct tcp_zerocopy_receive *zc,
				   struct sk_buff *skb, u32 copylen,
				   u32 *offset, u32 *seq)
@@ -1917,6 +1947,8 @@ static int tcp_zerocopy_receive(struct sock *sk,
	ret = 0;
	curr_addr = address;
	while (length + PAGE_SIZE <= zc->length) {
		int mappable_offset;

		if (zc->recv_skip_hint < PAGE_SIZE) {
			u32 offset_frag;

@@ -1944,15 +1976,11 @@ static int tcp_zerocopy_receive(struct sock *sk,
			if (!frags || offset_frag)
				break;
		}
		if (skb_frag_size(frags) != PAGE_SIZE || skb_frag_off(frags)) {
			int remaining = zc->recv_skip_hint;

			while (remaining && (skb_frag_size(frags) != PAGE_SIZE ||
					     skb_frag_off(frags))) {
				remaining -= skb_frag_size(frags);
				frags++;
			}
			zc->recv_skip_hint -= remaining;
		mappable_offset = find_next_mappable_frag(frags,
							  zc->recv_skip_hint);
		if (mappable_offset) {
			zc->recv_skip_hint = mappable_offset;
			break;
		}
		pages[pg_idx] = skb_frag_page(frags);