Commit af8a2b8b authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: fix invalid reference to the index variable of the iterator



Now in sctp_apply_peer_addr_params(), if SPP_IPV6_FLOWLABEL flag is set
and trans is NULL, it would use trans as the index variable to traverse
transport_addr_list, then trans is set as the last transport of it.

Later, if SPP_DSCP flag is set, it would enter into the wrong branch as
trans is actually an invalid reference.

So fix it by using a new index variable to traverse transport_addr_list
for both SPP_DSCP and SPP_IPV6_FLOWLABEL flags process.

Fixes: 0b0dce7a ("sctp: add spp_ipv6_flowlabel and spp_dscp for sctp_paddrparams")
Reported-by: default avatarJulia Lawall <julia.lawall@lip6.fr>
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf68066f
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -2663,14 +2663,15 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
					   SCTP_FLOWLABEL_VAL_MASK;
			trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
		} else if (asoc) {
			list_for_each_entry(trans,
					    &asoc->peer.transport_addr_list,
			struct sctp_transport *t;

			list_for_each_entry(t, &asoc->peer.transport_addr_list,
					    transports) {
				if (trans->ipaddr.sa.sa_family != AF_INET6)
				if (t->ipaddr.sa.sa_family != AF_INET6)
					continue;
				trans->flowlabel = params->spp_ipv6_flowlabel &
				t->flowlabel = params->spp_ipv6_flowlabel &
					       SCTP_FLOWLABEL_VAL_MASK;
				trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
				t->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
			}
			asoc->flowlabel = params->spp_ipv6_flowlabel &
					  SCTP_FLOWLABEL_VAL_MASK;
@@ -2687,12 +2688,13 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
			trans->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
			trans->dscp |= SCTP_DSCP_SET_MASK;
		} else if (asoc) {
			list_for_each_entry(trans,
					    &asoc->peer.transport_addr_list,
			struct sctp_transport *t;

			list_for_each_entry(t, &asoc->peer.transport_addr_list,
					    transports) {
				trans->dscp = params->spp_dscp &
				t->dscp = params->spp_dscp &
					  SCTP_DSCP_VAL_MASK;
				trans->dscp |= SCTP_DSCP_SET_MASK;
				t->dscp |= SCTP_DSCP_SET_MASK;
			}
			asoc->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
			asoc->dscp |= SCTP_DSCP_SET_MASK;