On Mon, Jan 23, 2023 at 1:00 PM Marcelo Ricardo Leitner <marcelo.leitner@xxxxxxxxx> wrote: > > Currently, if you bind the socket to something like: > servaddr.sin6_family = AF_INET6; > servaddr.sin6_port = htons(0); > servaddr.sin6_scope_id = 0; > inet_pton(AF_INET6, "::1", &servaddr.sin6_addr); > > And then request a connect to: > connaddr.sin6_family = AF_INET6; > connaddr.sin6_port = htons(20000); > connaddr.sin6_scope_id = if_nametoindex("lo"); > inet_pton(AF_INET6, "fe88::1", &connaddr.sin6_addr); > > What the stack does is: > - bind the socket > - create a new asoc > - to handle the connect > - copy the addresses that can be used for the given scope > - try to connect > > But the copy returns 0 addresses, and the effect is that it ends up > trying to connect as if the socket wasn't bound, which is not the > desired behavior. This unexpected behavior also allows KASLR leaks > through SCTP diag interface. > > The fix here then is, if when trying to copy the addresses that can > be used for the scope used in connect() it returns 0 addresses, bail > out. This is what TCP does with a similar reproducer. > > Reported-by: Pietro Borrello <borrello@xxxxxxxxxxxxxxxx> > Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@xxxxxxxxx> > --- > net/sctp/bind_addr.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c > index 59e653b528b1faec6c6fcf73f0dd42633880e08d..6b95d3ba8fe1cecf4d75956bf87546b1f1a81c4f 100644 > --- a/net/sctp/bind_addr.c > +++ b/net/sctp/bind_addr.c > @@ -73,6 +73,12 @@ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest, > } > } > > + /* If somehow no addresses were found that can be used with this > + * scope, it's an error. > + */ > + if (list_empty(&dest->address_list)) > + error = -ENETUNREACH; > + > out: > if (error) > sctp_bind_addr_clean(dest); > -- > 2.39.0 > Reviewed-by: Xin Long <lucien.xin@xxxxxxxxx>