Skip to content

Commit aa5d8f3

Browse files
Qihangsmfrench
authored andcommitted
ksmbd: pin conn during async oplock break notification
smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn pointer in an async ksmbd_work and then queue that work on ksmbd-io. The work only increments conn->r_count, which prevents teardown from passing the pending-request wait after the increment, but it does not pin the struct ksmbd_conn object. If connection teardown races with an oplock break notification, the last conn reference can be dropped before the queued worker finishes. The worker then uses the freed conn in ksmbd_conn_write() and ksmbd_conn_r_count_dec(). Take a real conn reference when publishing the conn pointer to the async work item, and drop it after the notification work has decremented r_count. Apply the same lifetime rule to lease break notification, which uses the same work->conn pattern. Fixes: 3aa660c ("ksmbd: prevent connection release during oplock break notification") Signed-off-by: Qihang <q.h.hack.winter@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 1c0ae3d commit aa5d8f3

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

fs/smb/server/oplock.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
875875
out:
876876
ksmbd_free_work_struct(work);
877877
ksmbd_conn_r_count_dec(conn);
878+
ksmbd_conn_put(conn);
878879
}
879880

880881
/**
@@ -910,7 +911,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
910911
br_info->open_trunc = opinfo->open_trunc;
911912

912913
work->request_buf = (char *)br_info;
913-
work->conn = conn;
914+
work->conn = ksmbd_conn_get(conn);
914915
work->sess = opinfo->sess;
915916

916917
ksmbd_conn_r_count_inc(conn);
@@ -985,6 +986,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
985986
out:
986987
ksmbd_free_work_struct(work);
987988
ksmbd_conn_r_count_dec(conn);
989+
ksmbd_conn_put(conn);
988990
}
989991

990992
/**
@@ -1034,7 +1036,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo, bool wait_ack,
10341036
memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
10351037

10361038
work->request_buf = (char *)br_info;
1037-
work->conn = conn;
1039+
work->conn = ksmbd_conn_get(conn);
10381040
work->sess = opinfo->sess;
10391041

10401042
ksmbd_conn_r_count_inc(conn);

0 commit comments

Comments
 (0)