Unverified Commit 6dc08b44 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!1131 [sync] PR-1081: some backport bugfix for sockmap

Merge Pull Request from: @openeuler-sync-bot 
 

Origin pull request: 
https://gitee.com/openeuler/kernel/pulls/1081 
 
PR sync from:  Liu Jian <liujian56@huawei.com>
 https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/thread/24ZK7TI2Q55BY7U53AB2LYQUFTABZR4L/ 
some backport bugfix for sockmap

Cong Wang (1):
  bpf, sock_map: Move cancel_work_sync() out of sock lock

Eric Dumazet (1):
  net: deal with most data-races in sk_wait_event()

Jakub Sitnicki (2):
  bpf, sockmap: Check for any of tcp_bpf_prots when cloning a listener
  bpf, sockmap: Don't let sock_map_{close,destroy,unhash} call itself

Pengcheng Yang (3):
  bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data
  bpf, sockmap: Fix missing BPF_F_INGRESS flag when using apply_bytes
  bpf, sockmap: Fix data loss caused by using apply_bytes on ingress
    redirect

Wang Yufen (1):
  bpf, sockmap: Fix the sk->sk_forward_alloc warning of
    sk_stream_kill_queues

zhangmingyi (1):
  bpf: fix bpf_tcp_ingress addr use after free


-- 
2.34.1
 
 
Link:https://gitee.com/openeuler/kernel/pulls/1131

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 0e6a6ad6 04f26fce
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ struct sk_psock {
	u32				apply_bytes;
	u32				cork_bytes;
	u32				eval;
	bool				redir_ingress; /* undefined if sk_redir is null */
	struct sk_msg			*cork;
	struct sk_psock_progs		progs;
	struct sk_psock_parser		parser;
@@ -393,7 +394,7 @@ static inline void sk_psock_report_error(struct sk_psock *psock, int err)
}

struct sk_psock *sk_psock_init(struct sock *sk, int node);
void sk_psock_stop(struct sk_psock *psock, bool wait);
void sk_psock_stop(struct sk_psock *psock);

int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock);
void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock);
+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
+2 −2
Original line number Diff line number Diff line
@@ -2238,8 +2238,8 @@ static inline void tcp_bpf_clone(const struct sock *sk, struct sock *newsk)
#endif /* CONFIG_BPF_STREAM_PARSER */

#ifdef CONFIG_NET_SOCK_MSG
int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, u32 bytes,
			  int flags);
int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress,
			struct sk_msg *msg, u32 bytes, int flags);
int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock,
		      struct msghdr *msg, int len, int flags);
#endif /* CONFIG_NET_SOCK_MSG */
+8 −8
Original line number Diff line number Diff line
@@ -695,16 +695,13 @@ static void sk_psock_link_destroy(struct sk_psock *psock)
	}
}

void sk_psock_stop(struct sk_psock *psock, bool wait)
void sk_psock_stop(struct sk_psock *psock)
{
	spin_lock_bh(&psock->ingress_lock);
	sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
	sk_psock_cork_free(psock);
	__sk_psock_zap_ingress(psock);
	spin_unlock_bh(&psock->ingress_lock);

	if (wait)
		cancel_work_sync(&psock->work);
}

static void sk_psock_destroy_deferred(struct work_struct *gc)
@@ -750,7 +747,7 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock)
		sk_psock_stop_verdict(sk, psock);
	write_unlock_bh(&sk->sk_callback_lock);

	sk_psock_stop(psock, false);
	sk_psock_stop(psock);
	call_rcu(&psock->rcu, sk_psock_destroy);
}
EXPORT_SYMBOL_GPL(sk_psock_drop);
@@ -787,13 +784,16 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock,
	ret = sk_psock_map_verd(ret, msg->sk_redir);
	psock->apply_bytes = msg->apply_bytes;
	if (ret == __SK_REDIRECT) {
		if (psock->sk_redir)
		if (psock->sk_redir) {
			sock_put(psock->sk_redir);
		psock->sk_redir = msg->sk_redir;
		if (!psock->sk_redir) {
			psock->sk_redir = NULL;
		}
		if (!msg->sk_redir) {
			ret = __SK_DROP;
			goto out;
		}
		psock->redir_ingress = sk_msg_to_ingress(msg);
		psock->sk_redir = msg->sk_redir;
		sock_hold(psock->sk_redir);
	}
out:
+34 −26
Original line number Diff line number Diff line
@@ -1623,14 +1623,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);
}

@@ -1643,16 +1644,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_stop(psock);
		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);
@@ -1668,15 +1670,21 @@ 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);
		sk_psock_stop(psock);
		release_sock(sk);
		cancel_work_sync(&psock->work);
		sk_psock_put(sk, psock);
	}
	/* 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);
}

Loading