Unverified Commit 77f81511 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8294 CVE-2023-52735

Merge Pull Request from: @ci-robot 
 
PR sync from: Pu Lehui <pulehui@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/GZ2V2NKPCAVTCSUZEATLJ7CDH2RAEMS5/ 
Jakub Sitnicki (2):
  bpf, sockmap: Don't let sock_map_{close,destroy,unhash} call itself
  bpf, sockmap: Check for any of tcp_bpf_prots when cloning a listener


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/I9R4KX
https://gitee.com/openeuler/kernel/issues/I9R4KX 
 
Link:https://gitee.com/openeuler/kernel/pulls/8294

 

Reviewed-by: default avatarYe Weihua <yeweihua4@huawei.com>
Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents a70a9e61 156241ee
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -38,4 +38,16 @@
 */
#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=)

/**
 * is_insidevar - check if the @ptr points inside the @var memory range.
 * @ptr:	the pointer to a memory address.
 * @var:	the variable which address and size identify the memory range.
 *
 * Evaluates to true if the address in @ptr lies within the memory
 * range allocated to @var.
 */
#define is_insidevar(ptr, var)						\
	((uintptr_t)(ptr) >= (uintptr_t)(var) &&			\
	 (uintptr_t)(ptr) <  (uintptr_t)(var) + sizeof(var))

#endif
+33 −26
Original line number Diff line number Diff line
@@ -1561,14 +1561,15 @@ void sock_map_unhash(struct sock *sk)
	psock = sk_psock(sk);
	if (unlikely(!psock)) {
		rcu_read_unlock();
		if (sk->sk_prot->unhash)
			sk->sk_prot->unhash(sk);
		return;
	}

		saved_unhash = READ_ONCE(sk->sk_prot)->unhash;
	} else {
		saved_unhash = psock->saved_unhash;
		sock_map_remove_links(sk, psock);
		rcu_read_unlock();
	}
	if (WARN_ON_ONCE(saved_unhash == sock_map_unhash))
		return;
	if (saved_unhash)
		saved_unhash(sk);
}

@@ -1581,16 +1582,17 @@ void sock_map_destroy(struct sock *sk)
	psock = sk_psock_get(sk);
	if (unlikely(!psock)) {
		rcu_read_unlock();
		if (sk->sk_prot->destroy)
			sk->sk_prot->destroy(sk);
		return;
	}

		saved_destroy = READ_ONCE(sk->sk_prot)->destroy;
	} else {
		saved_destroy = psock->saved_destroy;
		sock_map_remove_links(sk, psock);
		rcu_read_unlock();
		sk_psock_stop(psock, false);
		sk_psock_put(sk, psock);
	}
	if (WARN_ON_ONCE(saved_destroy == sock_map_destroy))
		return;
	if (saved_destroy)
		saved_destroy(sk);
}
EXPORT_SYMBOL_GPL(sock_map_destroy);
@@ -1606,15 +1608,20 @@ void sock_map_close(struct sock *sk, long timeout)
	if (unlikely(!psock)) {
		rcu_read_unlock();
		release_sock(sk);
		return sk->sk_prot->close(sk, timeout);
	}

		saved_close = READ_ONCE(sk->sk_prot)->close;
	} else {
		saved_close = psock->saved_close;
		sock_map_remove_links(sk, psock);
		rcu_read_unlock();
		sk_psock_stop(psock, true);
		sk_psock_put(sk, psock);
		release_sock(sk);
	}
	/* Make sure we do not recurse. This is a bug.
	 * Leak the socket instead of crashing on a stack overflow.
	 */
	if (WARN_ON_ONCE(saved_close == sock_map_close))
		return;
	saved_close(sk, timeout);
}

+2 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/bpf.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/util_macros.h>

#include <net/inet_common.h>
#include <net/tls.h>
@@ -719,10 +720,9 @@ struct proto *tcp_bpf_get_proto(struct sock *sk, struct sk_psock *psock)
 */
void tcp_bpf_clone(const struct sock *sk, struct sock *newsk)
{
	int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4;
	struct proto *prot = newsk->sk_prot;

	if (prot == &tcp_bpf_prots[family][TCP_BPF_BASE])
	if (is_insidevar(prot, tcp_bpf_prots))
		newsk->sk_prot = sk->sk_prot_creator;
}
#endif /* CONFIG_BPF_STREAM_PARSER */