]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.170/vsock-send-reset-control-packet-when-socket-is-partially-bound.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.4.170 / vsock-send-reset-control-packet-when-socket-is-partially-bound.patch
1 From foo@baz Sat Jan 5 08:30:28 CET 2019
2 From: Jorgen Hansen <jhansen@vmware.com>
3 Date: Tue, 18 Dec 2018 00:34:06 -0800
4 Subject: VSOCK: Send reset control packet when socket is partially bound
5
6 From: Jorgen Hansen <jhansen@vmware.com>
7
8 [ Upstream commit a915b982d8f5e4295f64b8dd37ce753874867e88 ]
9
10 If a server side socket is bound to an address, but not in the listening
11 state yet, incoming connection requests should receive a reset control
12 packet in response. However, the function used to send the reset
13 silently drops the reset packet if the sending socket isn't bound
14 to a remote address (as is the case for a bound socket not yet in
15 the listening state). This change fixes this by using the src
16 of the incoming packet as destination for the reset packet in
17 this case.
18
19 Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
20 Reviewed-by: Adit Ranadive <aditr@vmware.com>
21 Reviewed-by: Vishnu Dasa <vdasa@vmware.com>
22 Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
23 Signed-off-by: David S. Miller <davem@davemloft.net>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25 ---
26 net/vmw_vsock/vmci_transport.c | 67 ++++++++++++++++++++++++++++++-----------
27 1 file changed, 50 insertions(+), 17 deletions(-)
28
29 --- a/net/vmw_vsock/vmci_transport.c
30 +++ b/net/vmw_vsock/vmci_transport.c
31 @@ -273,6 +273,31 @@ vmci_transport_send_control_pkt_bh(struc
32 }
33
34 static int
35 +vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src,
36 + struct sockaddr_vm *dst,
37 + enum vmci_transport_packet_type type,
38 + u64 size,
39 + u64 mode,
40 + struct vmci_transport_waiting_info *wait,
41 + u16 proto,
42 + struct vmci_handle handle)
43 +{
44 + struct vmci_transport_packet *pkt;
45 + int err;
46 +
47 + pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
48 + if (!pkt)
49 + return -ENOMEM;
50 +
51 + err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size,
52 + mode, wait, proto, handle,
53 + true);
54 + kfree(pkt);
55 +
56 + return err;
57 +}
58 +
59 +static int
60 vmci_transport_send_control_pkt(struct sock *sk,
61 enum vmci_transport_packet_type type,
62 u64 size,
63 @@ -281,9 +306,7 @@ vmci_transport_send_control_pkt(struct s
64 u16 proto,
65 struct vmci_handle handle)
66 {
67 - struct vmci_transport_packet *pkt;
68 struct vsock_sock *vsk;
69 - int err;
70
71 vsk = vsock_sk(sk);
72
73 @@ -293,17 +316,10 @@ vmci_transport_send_control_pkt(struct s
74 if (!vsock_addr_bound(&vsk->remote_addr))
75 return -EINVAL;
76
77 - pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
78 - if (!pkt)
79 - return -ENOMEM;
80 -
81 - err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr,
82 - &vsk->remote_addr, type, size,
83 - mode, wait, proto, handle,
84 - true);
85 - kfree(pkt);
86 -
87 - return err;
88 + return vmci_transport_alloc_send_control_pkt(&vsk->local_addr,
89 + &vsk->remote_addr,
90 + type, size, mode,
91 + wait, proto, handle);
92 }
93
94 static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
95 @@ -321,12 +337,29 @@ static int vmci_transport_send_reset_bh(
96 static int vmci_transport_send_reset(struct sock *sk,
97 struct vmci_transport_packet *pkt)
98 {
99 + struct sockaddr_vm *dst_ptr;
100 + struct sockaddr_vm dst;
101 + struct vsock_sock *vsk;
102 +
103 if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST)
104 return 0;
105 - return vmci_transport_send_control_pkt(sk,
106 - VMCI_TRANSPORT_PACKET_TYPE_RST,
107 - 0, 0, NULL, VSOCK_PROTO_INVALID,
108 - VMCI_INVALID_HANDLE);
109 +
110 + vsk = vsock_sk(sk);
111 +
112 + if (!vsock_addr_bound(&vsk->local_addr))
113 + return -EINVAL;
114 +
115 + if (vsock_addr_bound(&vsk->remote_addr)) {
116 + dst_ptr = &vsk->remote_addr;
117 + } else {
118 + vsock_addr_init(&dst, pkt->dg.src.context,
119 + pkt->src_port);
120 + dst_ptr = &dst;
121 + }
122 + return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, dst_ptr,
123 + VMCI_TRANSPORT_PACKET_TYPE_RST,
124 + 0, 0, NULL, VSOCK_PROTO_INVALID,
125 + VMCI_INVALID_HANDLE);
126 }
127
128 static int vmci_transport_send_negotiate(struct sock *sk, size_t size)