Unverified Commit 5c7ed853 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6082 can: j1939: Fix UAF in j1939_sk_match_filter during setsockopt(SO_J1939_FILTER)

parents 42bf10ff c9ae3bfe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ struct j1939_sock {

	int ifindex;
	struct j1939_addr addr;
	spinlock_t filters_lock;
	struct j1939_filter *filters;
	int nfilters;
	pgn_t pgn_rx_filter;
+18 −4
Original line number Diff line number Diff line
@@ -262,12 +262,17 @@ static bool j1939_sk_match_dst(struct j1939_sock *jsk,
static bool j1939_sk_match_filter(struct j1939_sock *jsk,
				  const struct j1939_sk_buff_cb *skcb)
{
	const struct j1939_filter *f = jsk->filters;
	int nfilter = jsk->nfilters;
	const struct j1939_filter *f;
	int nfilter;

	spin_lock_bh(&jsk->filters_lock);

	f = jsk->filters;
	nfilter = jsk->nfilters;

	if (!nfilter)
		/* receive all when no filters are assigned */
		return true;
		goto filter_match_found;

	for (; nfilter; ++f, --nfilter) {
		if ((skcb->addr.pgn & f->pgn_mask) != f->pgn)
@@ -276,9 +281,15 @@ static bool j1939_sk_match_filter(struct j1939_sock *jsk,
			continue;
		if ((skcb->addr.src_name & f->name_mask) != f->name)
			continue;
		return true;
		goto filter_match_found;
	}

	spin_unlock_bh(&jsk->filters_lock);
	return false;

filter_match_found:
	spin_unlock_bh(&jsk->filters_lock);
	return true;
}

static bool j1939_sk_recv_match_one(struct j1939_sock *jsk,
@@ -401,6 +412,7 @@ static int j1939_sk_init(struct sock *sk)
	atomic_set(&jsk->skb_pending, 0);
	spin_lock_init(&jsk->sk_session_queue_lock);
	INIT_LIST_HEAD(&jsk->sk_session_queue);
	spin_lock_init(&jsk->filters_lock);

	/* j1939_sk_sock_destruct() depends on SOCK_RCU_FREE flag */
	sock_set_flag(sk, SOCK_RCU_FREE);
@@ -703,9 +715,11 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
		}

		lock_sock(&jsk->sk);
		spin_lock_bh(&jsk->filters_lock);
		ofilters = jsk->filters;
		jsk->filters = filters;
		jsk->nfilters = count;
		spin_unlock_bh(&jsk->filters_lock);
		release_sock(&jsk->sk);
		kfree(ofilters);
		return 0;