Skip to content

Commit 50f930d

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: fix potential use-after-free in oplock/lease break ack
If ksmbd_iov_pin_rsp return error, use-after-free can happen by accessing opinfo->state and opinfo_put and ksmbd_fd_put could called twice. Reported-by: Ziyan Xu <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 277627b commit 50f930d

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

fs/smb/server/smb2pdu.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8573,28 +8573,22 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
85738573
goto err_out;
85748574
}
85758575

8576-
opinfo->op_state = OPLOCK_STATE_NONE;
8577-
wake_up_interruptible_all(&opinfo->oplock_q);
8578-
opinfo_put(opinfo);
8579-
ksmbd_fd_put(work, fp);
8580-
85818576
rsp->StructureSize = cpu_to_le16(24);
85828577
rsp->OplockLevel = rsp_oplevel;
85838578
rsp->Reserved = 0;
85848579
rsp->Reserved2 = 0;
85858580
rsp->VolatileFid = volatile_id;
85868581
rsp->PersistentFid = persistent_id;
85878582
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8588-
if (!ret)
8589-
return;
8590-
8583+
if (ret) {
85918584
err_out:
8585+
smb2_set_err_rsp(work);
8586+
}
8587+
85928588
opinfo->op_state = OPLOCK_STATE_NONE;
85938589
wake_up_interruptible_all(&opinfo->oplock_q);
8594-
85958590
opinfo_put(opinfo);
85968591
ksmbd_fd_put(work, fp);
8597-
smb2_set_err_rsp(work);
85988592
}
85998593

86008594
static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -8724,11 +8718,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
87248718
}
87258719

87268720
lease_state = lease->state;
8727-
opinfo->op_state = OPLOCK_STATE_NONE;
8728-
wake_up_interruptible_all(&opinfo->oplock_q);
8729-
atomic_dec(&opinfo->breaking_cnt);
8730-
wake_up_interruptible_all(&opinfo->oplock_brk);
8731-
opinfo_put(opinfo);
87328721

87338722
rsp->StructureSize = cpu_to_le16(36);
87348723
rsp->Reserved = 0;
@@ -8737,16 +8726,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
87378726
rsp->LeaseState = lease_state;
87388727
rsp->LeaseDuration = 0;
87398728
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8740-
if (!ret)
8741-
return;
8742-
8729+
if (ret) {
87438730
err_out:
8731+
smb2_set_err_rsp(work);
8732+
}
8733+
8734+
opinfo->op_state = OPLOCK_STATE_NONE;
87448735
wake_up_interruptible_all(&opinfo->oplock_q);
87458736
atomic_dec(&opinfo->breaking_cnt);
87468737
wake_up_interruptible_all(&opinfo->oplock_brk);
8747-
87488738
opinfo_put(opinfo);
8749-
smb2_set_err_rsp(work);
87508739
}
87518740

87528741
/**

0 commit comments

Comments
 (0)