Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22e76c84 authored by Nelson Elhage's avatar Nelson Elhage Committed by David S. Miller
Browse files

inet_diag: Make sure we actually run the same bytecode we audited.



We were using nlmsg_find_attr() to look up the bytecode by attribute when
auditing, but then just using the first attribute when actually running
bytecode. So, if we received a message with two attribute elements, where only
the second had type INET_DIAG_REQ_BYTECODE, we would validate and run different
bytecode strings.

Fix this by consistently using nlmsg_find_attr everywhere.

Signed-off-by: default avatarNelson Elhage <nelhage@ksplice.com>
Signed-off-by: default avatarThomas Graf <tgraf@infradead.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6b8c92ba
Loading
Loading
Loading
Loading
+16 −11
Original line number Original line Diff line number Diff line
@@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk,
{
{
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);


	if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
	if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
		struct inet_diag_entry entry;
		struct inet_diag_entry entry;
		struct rtattr *bc = (struct rtattr *)(r + 1);
		const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
							  sizeof(*r),
							  INET_DIAG_REQ_BYTECODE);
		struct inet_sock *inet = inet_sk(sk);
		struct inet_sock *inet = inet_sk(sk);


		entry.family = sk->sk_family;
		entry.family = sk->sk_family;
@@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk,
		entry.dport = ntohs(inet->inet_dport);
		entry.dport = ntohs(inet->inet_dport);
		entry.userlocks = sk->sk_userlocks;
		entry.userlocks = sk->sk_userlocks;


		if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
		if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
			return 0;
			return 0;
	}
	}


@@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
{
{
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);


	if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
	if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
		struct inet_diag_entry entry;
		struct inet_diag_entry entry;
		struct rtattr *bc = (struct rtattr *)(r + 1);
		const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
							  sizeof(*r),
							  INET_DIAG_REQ_BYTECODE);


		entry.family = tw->tw_family;
		entry.family = tw->tw_family;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
		entry.dport = ntohs(tw->tw_dport);
		entry.dport = ntohs(tw->tw_dport);
		entry.userlocks = 0;
		entry.userlocks = 0;


		if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
		if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
			return 0;
			return 0;
	}
	}


@@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
	struct inet_connection_sock *icsk = inet_csk(sk);
	struct inet_connection_sock *icsk = inet_csk(sk);
	struct listen_sock *lopt;
	struct listen_sock *lopt;
	struct rtattr *bc = NULL;
	const struct nlattr *bc = NULL;
	struct inet_sock *inet = inet_sk(sk);
	struct inet_sock *inet = inet_sk(sk);
	int j, s_j;
	int j, s_j;
	int reqnum, s_reqnum;
	int reqnum, s_reqnum;
@@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
	if (!lopt || !lopt->qlen)
	if (!lopt || !lopt->qlen)
		goto out;
		goto out;


	if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
	if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
		bc = (struct rtattr *)(r + 1);
		bc = nlmsg_find_attr(cb->nlh, sizeof(*r),
				     INET_DIAG_REQ_BYTECODE);
		entry.sport = inet->inet_num;
		entry.sport = inet->inet_num;
		entry.userlocks = sk->sk_userlocks;
		entry.userlocks = sk->sk_userlocks;
	}
	}
@@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
					&ireq->rmt_addr;
					&ireq->rmt_addr;
				entry.dport = ntohs(ireq->rmt_port);
				entry.dport = ntohs(ireq->rmt_port);


				if (!inet_diag_bc_run(RTA_DATA(bc),
				if (!inet_diag_bc_run(nla_data(bc),
						    RTA_PAYLOAD(bc), &entry))
						      nla_len(bc), &entry))
					continue;
					continue;
			}
			}