Unverified Commit 3e6d44ea authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11282 CVE-2024-44935

Merge Pull Request from: @ci-robot 
 
PR sync from: Liu Jian <liujian56@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/CUTEKCGQV7USNC7NHJCW6TFFTK7BIDJP/ 
CVE-2024-44935

Kuniyuki Iwashima (1):
  sctp: Fix null-ptr-deref in reuseport_add_sock().

Xin Long (1):
  sctp: move hlist_node and hashent out of sctp_ep_common


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IAMMC2 
 
Link:https://gitee.com/openeuler/kernel/pulls/11282

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 541f0a5d 9a9c34c5
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -506,8 +506,8 @@ static inline int sctp_ep_hashfn(struct net *net, __u16 lport)
	return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1);
}

#define sctp_for_each_hentry(epb, head) \
	hlist_for_each_entry(epb, head, node)
#define sctp_for_each_hentry(ep, head) \
	hlist_for_each_entry(ep, head, node)

/* Is a socket of this style? */
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
+4 −4
Original line number Diff line number Diff line
@@ -1218,10 +1218,6 @@ enum sctp_endpoint_type {
 */

struct sctp_ep_common {
	/* Fields to help us manage our entries in the hash tables. */
	struct hlist_node node;
	int hashent;

	/* Runtime type information.  What kind of endpoint is this? */
	enum sctp_endpoint_type type;

@@ -1273,6 +1269,10 @@ struct sctp_endpoint {
	/* Common substructure for endpoint and association. */
	struct sctp_ep_common base;

	/* Fields to help us manage our entries in the hash tables. */
	struct hlist_node node;
	int hashent;

	/* Associations: A list of current associations and mappings
	 *	      to the data consumers for each association. This
	 *	      may be in the form of a hash table or other
+21 −25
Original line number Diff line number Diff line
@@ -723,23 +723,25 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
	struct sock *sk = ep->base.sk;
	struct net *net = sock_net(sk);
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;
	int err = 0;

	epb = &ep->base;
	epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port);
	head = &sctp_ep_hashtable[epb->hashent];
	ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port);
	head = &sctp_ep_hashtable[ep->hashent];

	write_lock(&head->lock);
	if (sk->sk_reuseport) {
		bool any = sctp_is_ep_boundall(sk);
		struct sctp_ep_common *epb2;
		struct sctp_endpoint *ep2;
		struct list_head *list;
		int cnt = 0, err = 1;
		int cnt = 0;

		err = 1;

		list_for_each(list, &ep->base.bind_addr.address_list)
			cnt++;

		sctp_for_each_hentry(epb2, &head->chain) {
			struct sock *sk2 = epb2->sk;
		sctp_for_each_hentry(ep2, &head->chain) {
			struct sock *sk2 = ep2->base.sk;

			if (!net_eq(sock_net(sk2), net) || sk2 == sk ||
			    !uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) ||
@@ -751,24 +753,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
			if (!err) {
				err = reuseport_add_sock(sk, sk2, any);
				if (err)
					return err;
					goto out;
				break;
			} else if (err < 0) {
				return err;
				goto out;
			}
		}

		if (err) {
			err = reuseport_alloc(sk, any);
			if (err)
				return err;
				goto out;
		}
	}

	write_lock(&head->lock);
	hlist_add_head(&epb->node, &head->chain);
	hlist_add_head(&ep->node, &head->chain);
out:
	write_unlock(&head->lock);
	return 0;
	return err;
}

/* Add an endpoint to the hash. Local BH-safe. */
@@ -788,19 +790,15 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
{
	struct sock *sk = ep->base.sk;
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;

	epb = &ep->base;
	ep->hashent = sctp_ep_hashfn(sock_net(sk), ep->base.bind_addr.port);

	epb->hashent = sctp_ep_hashfn(sock_net(sk), epb->bind_addr.port);

	head = &sctp_ep_hashtable[epb->hashent];
	head = &sctp_ep_hashtable[ep->hashent];

	write_lock(&head->lock);
	if (rcu_access_pointer(sk->sk_reuseport_cb))
		reuseport_detach_sock(sk);

	write_lock(&head->lock);
	hlist_del_init(&epb->node);
	hlist_del_init(&ep->node);
	write_unlock(&head->lock);
}

@@ -833,7 +831,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
					const union sctp_addr *paddr)
{
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;
	struct sctp_endpoint *ep;
	struct sock *sk;
	__be16 lport;
@@ -843,8 +840,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
	hash = sctp_ep_hashfn(net, ntohs(lport));
	head = &sctp_ep_hashtable[hash];
	read_lock(&head->lock);
	sctp_for_each_hentry(epb, &head->chain) {
		ep = sctp_ep(epb);
	sctp_for_each_hentry(ep, &head->chain) {
		if (sctp_endpoint_is_match(ep, net, laddr))
			goto hit;
	}
+4 −6
Original line number Diff line number Diff line
@@ -161,7 +161,6 @@ static void *sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static int sctp_eps_seq_show(struct seq_file *seq, void *v)
{
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;
	struct sctp_endpoint *ep;
	struct sock *sk;
	int    hash = *(loff_t *)v;
@@ -171,18 +170,17 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)

	head = &sctp_ep_hashtable[hash];
	read_lock_bh(&head->lock);
	sctp_for_each_hentry(epb, &head->chain) {
		ep = sctp_ep(epb);
		sk = epb->sk;
	sctp_for_each_hentry(ep, &head->chain) {
		sk = ep->base.sk;
		if (!net_eq(sock_net(sk), seq_file_net(seq)))
			continue;
		seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu ", ep, sk,
			   sctp_sk(sk)->type, sk->sk_state, hash,
			   epb->bind_addr.port,
			   ep->base.bind_addr.port,
			   from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
			   sock_i_ino(sk));

		sctp_seq_dump_local_addrs(seq, epb);
		sctp_seq_dump_local_addrs(seq, &ep->base);
		seq_printf(seq, "\n");
	}
	read_unlock_bh(&head->lock);
+3 −3
Original line number Diff line number Diff line
@@ -5193,14 +5193,14 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
			   void *p) {
	int err = 0;
	int hash = 0;
	struct sctp_ep_common *epb;
	struct sctp_endpoint *ep;
	struct sctp_hashbucket *head;

	for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
	     hash++, head++) {
		read_lock_bh(&head->lock);
		sctp_for_each_hentry(epb, &head->chain) {
			err = cb(sctp_ep(epb), p);
		sctp_for_each_hentry(ep, &head->chain) {
			err = cb(ep, p);
			if (err)
				break;
		}