| From e21dba7a4df4d93da237da65a096084b4f2e87b4 Mon Sep 17 00:00:00 2001 |
| From: Martin Schiller <ms@dev.tdt.de> |
| Date: Thu, 9 Jan 2020 07:31:14 +0100 |
| Subject: net/x25: fix nonblocking connect |
| |
| From: Martin Schiller <ms@dev.tdt.de> |
| |
| commit e21dba7a4df4d93da237da65a096084b4f2e87b4 upstream. |
| |
| This patch fixes 2 issues in x25_connect(): |
| |
| 1. It makes absolutely no sense to reset the neighbour and the |
| connection state after a (successful) nonblocking call of x25_connect. |
| This prevents any connection from being established, since the response |
| (call accept) cannot be processed. |
| |
| 2. Any further calls to x25_connect() while a call is pending should |
| simply return, instead of creating new Call Request (on different |
| logical channels). |
| |
| This patch should also fix the "KASAN: null-ptr-deref Write in |
| x25_connect" and "BUG: unable to handle kernel NULL pointer dereference |
| in x25_connect" bugs reported by syzbot. |
| |
| Signed-off-by: Martin Schiller <ms@dev.tdt.de> |
| Reported-by: syzbot+429c200ffc8772bfe070@syzkaller.appspotmail.com |
| Reported-by: syzbot+eec0c87f31a7c3b66f7b@syzkaller.appspotmail.com |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/x25/af_x25.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/net/x25/af_x25.c |
| +++ b/net/x25/af_x25.c |
| @@ -764,6 +764,10 @@ static int x25_connect(struct socket *so |
| if (sk->sk_state == TCP_ESTABLISHED) |
| goto out; |
| |
| + rc = -EALREADY; /* Do nothing if call is already in progress */ |
| + if (sk->sk_state == TCP_SYN_SENT) |
| + goto out; |
| + |
| sk->sk_state = TCP_CLOSE; |
| sock->state = SS_UNCONNECTED; |
| |
| @@ -810,7 +814,7 @@ static int x25_connect(struct socket *so |
| /* Now the loop */ |
| rc = -EINPROGRESS; |
| if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) |
| - goto out_put_neigh; |
| + goto out; |
| |
| rc = x25_wait_for_connection_establishment(sk); |
| if (rc) |