Skip to content

Commit 36e55fd

Browse files
congwanggregkh
authored andcommitted
vsock: split dwork to avoid reinitializations
[ Upstream commit 455f05e ] syzbot reported that we reinitialize an active delayed work in vsock_stream_connect(): ODEBUG: init active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x90 kernel/workqueue.c:1414 WARNING: CPU: 1 PID: 11518 at lib/debugobjects.c:329 debug_print_object+0x16a/0x210 lib/debugobjects.c:326 The pattern is apparently wrong, we should only initialize the dealyed work once and could repeatly schedule it. So we have to move out the initializations to allocation side. And to avoid confusion, we can split the shared dwork into two, instead of re-using the same one. Fixes: d021c34 ("VSOCK: Introduce VM Sockets") Reported-by: <syzbot+8a9b1bd330476a4f3db6@syzkaller.appspotmail.com> Cc: Andy king <acking@vmware.com> Cc: Stefan Hajnoczi <stefanha@redhat.com> Cc: Jorgen Hansen <jhansen@vmware.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4396f50 commit 36e55fd

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed

include/net/af_vsock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ struct vsock_sock {
6262
struct list_head pending_links;
6363
struct list_head accept_queue;
6464
bool rejected;
65-
struct delayed_work dwork;
65+
struct delayed_work connect_work;
66+
struct delayed_work pending_work;
6667
struct delayed_work close_work;
6768
bool close_work_scheduled;
6869
u32 peer_shutdown;
@@ -75,7 +76,6 @@ struct vsock_sock {
7576

7677
s64 vsock_stream_has_data(struct vsock_sock *vsk);
7778
s64 vsock_stream_has_space(struct vsock_sock *vsk);
78-
void vsock_pending_work(struct work_struct *work);
7979
struct sock *__vsock_create(struct net *net,
8080
struct socket *sock,
8181
struct sock *parent,

net/vmw_vsock/af_vsock.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,14 @@ static int vsock_send_shutdown(struct sock *sk, int mode)
449449
return transport->shutdown(vsock_sk(sk), mode);
450450
}
451451

452-
void vsock_pending_work(struct work_struct *work)
452+
static void vsock_pending_work(struct work_struct *work)
453453
{
454454
struct sock *sk;
455455
struct sock *listener;
456456
struct vsock_sock *vsk;
457457
bool cleanup;
458458

459-
vsk = container_of(work, struct vsock_sock, dwork.work);
459+
vsk = container_of(work, struct vsock_sock, pending_work.work);
460460
sk = sk_vsock(vsk);
461461
listener = vsk->listener;
462462
cleanup = true;
@@ -496,7 +496,6 @@ void vsock_pending_work(struct work_struct *work)
496496
sock_put(sk);
497497
sock_put(listener);
498498
}
499-
EXPORT_SYMBOL_GPL(vsock_pending_work);
500499

501500
/**** SOCKET OPERATIONS ****/
502501

@@ -595,6 +594,8 @@ static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr)
595594
return retval;
596595
}
597596

597+
static void vsock_connect_timeout(struct work_struct *work);
598+
598599
struct sock *__vsock_create(struct net *net,
599600
struct socket *sock,
600601
struct sock *parent,
@@ -637,6 +638,8 @@ struct sock *__vsock_create(struct net *net,
637638
vsk->sent_request = false;
638639
vsk->ignore_connecting_rst = false;
639640
vsk->peer_shutdown = 0;
641+
INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
642+
INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
640643

641644
psk = parent ? vsock_sk(parent) : NULL;
642645
if (parent) {
@@ -1116,7 +1119,7 @@ static void vsock_connect_timeout(struct work_struct *work)
11161119
struct vsock_sock *vsk;
11171120
int cancel = 0;
11181121

1119-
vsk = container_of(work, struct vsock_sock, dwork.work);
1122+
vsk = container_of(work, struct vsock_sock, connect_work.work);
11201123
sk = sk_vsock(vsk);
11211124

11221125
lock_sock(sk);
@@ -1220,9 +1223,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
12201223
* timeout fires.
12211224
*/
12221225
sock_hold(sk);
1223-
INIT_DELAYED_WORK(&vsk->dwork,
1224-
vsock_connect_timeout);
1225-
schedule_delayed_work(&vsk->dwork, timeout);
1226+
schedule_delayed_work(&vsk->connect_work, timeout);
12261227

12271228
/* Skip ahead to preserve error code set above. */
12281229
goto out_wait;

net/vmw_vsock/vmci_transport.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,7 @@ static int vmci_transport_recv_listen(struct sock *sk,
10911091
vpending->listener = sk;
10921092
sock_hold(sk);
10931093
sock_hold(pending);
1094-
INIT_DELAYED_WORK(&vpending->dwork, vsock_pending_work);
1095-
schedule_delayed_work(&vpending->dwork, HZ);
1094+
schedule_delayed_work(&vpending->pending_work, HZ);
10961095

10971096
out:
10981097
return err;

0 commit comments

Comments
 (0)