Skip to content

Commit 97c3559

Browse files
namjaejeongregkh
authored andcommitted
ksmbd: fix potential use-after-free in oplock/lease break ack
commit 50f930d upstream. 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 <research@securitygossip.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8377d77 commit 97c3559

1 file changed

Lines changed: 9 additions & 20 deletions

File tree

fs/smb/server/smb2pdu.c

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

8506-
opinfo->op_state = OPLOCK_STATE_NONE;
8507-
wake_up_interruptible_all(&opinfo->oplock_q);
8508-
opinfo_put(opinfo);
8509-
ksmbd_fd_put(work, fp);
8510-
85118506
rsp->StructureSize = cpu_to_le16(24);
85128507
rsp->OplockLevel = rsp_oplevel;
85138508
rsp->Reserved = 0;
85148509
rsp->Reserved2 = 0;
85158510
rsp->VolatileFid = volatile_id;
85168511
rsp->PersistentFid = persistent_id;
85178512
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8518-
if (!ret)
8519-
return;
8520-
8513+
if (ret) {
85218514
err_out:
8515+
smb2_set_err_rsp(work);
8516+
}
8517+
85228518
opinfo->op_state = OPLOCK_STATE_NONE;
85238519
wake_up_interruptible_all(&opinfo->oplock_q);
8524-
85258520
opinfo_put(opinfo);
85268521
ksmbd_fd_put(work, fp);
8527-
smb2_set_err_rsp(work);
85288522
}
85298523

85308524
static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -8654,11 +8648,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
86548648
}
86558649

86568650
lease_state = lease->state;
8657-
opinfo->op_state = OPLOCK_STATE_NONE;
8658-
wake_up_interruptible_all(&opinfo->oplock_q);
8659-
atomic_dec(&opinfo->breaking_cnt);
8660-
wake_up_interruptible_all(&opinfo->oplock_brk);
8661-
opinfo_put(opinfo);
86628651

86638652
rsp->StructureSize = cpu_to_le16(36);
86648653
rsp->Reserved = 0;
@@ -8667,16 +8656,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
86678656
rsp->LeaseState = lease_state;
86688657
rsp->LeaseDuration = 0;
86698658
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8670-
if (!ret)
8671-
return;
8672-
8659+
if (ret) {
86738660
err_out:
8661+
smb2_set_err_rsp(work);
8662+
}
8663+
8664+
opinfo->op_state = OPLOCK_STATE_NONE;
86748665
wake_up_interruptible_all(&opinfo->oplock_q);
86758666
atomic_dec(&opinfo->breaking_cnt);
86768667
wake_up_interruptible_all(&opinfo->oplock_brk);
8677-
86788668
opinfo_put(opinfo);
8679-
smb2_set_err_rsp(work);
86808669
}
86818670

86828671
/**

0 commit comments

Comments
 (0)