Skip to content

Commit 815f116

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 2d89dab commit 815f116

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
@@ -8517,28 +8517,22 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
85178517
goto err_out;
85188518
}
85198519

8520-
opinfo->op_state = OPLOCK_STATE_NONE;
8521-
wake_up_interruptible_all(&opinfo->oplock_q);
8522-
opinfo_put(opinfo);
8523-
ksmbd_fd_put(work, fp);
8524-
85258520
rsp->StructureSize = cpu_to_le16(24);
85268521
rsp->OplockLevel = rsp_oplevel;
85278522
rsp->Reserved = 0;
85288523
rsp->Reserved2 = 0;
85298524
rsp->VolatileFid = volatile_id;
85308525
rsp->PersistentFid = persistent_id;
85318526
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8532-
if (!ret)
8533-
return;
8534-
8527+
if (ret) {
85358528
err_out:
8529+
smb2_set_err_rsp(work);
8530+
}
8531+
85368532
opinfo->op_state = OPLOCK_STATE_NONE;
85378533
wake_up_interruptible_all(&opinfo->oplock_q);
8538-
85398534
opinfo_put(opinfo);
85408535
ksmbd_fd_put(work, fp);
8541-
smb2_set_err_rsp(work);
85428536
}
85438537

85448538
static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -8668,11 +8662,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
86688662
}
86698663

86708664
lease_state = lease->state;
8671-
opinfo->op_state = OPLOCK_STATE_NONE;
8672-
wake_up_interruptible_all(&opinfo->oplock_q);
8673-
atomic_dec(&opinfo->breaking_cnt);
8674-
wake_up_interruptible_all(&opinfo->oplock_brk);
8675-
opinfo_put(opinfo);
86768665

86778666
rsp->StructureSize = cpu_to_le16(36);
86788667
rsp->Reserved = 0;
@@ -8681,16 +8670,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
86818670
rsp->LeaseState = lease_state;
86828671
rsp->LeaseDuration = 0;
86838672
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8684-
if (!ret)
8685-
return;
8686-
8673+
if (ret) {
86878674
err_out:
8675+
smb2_set_err_rsp(work);
8676+
}
8677+
8678+
opinfo->op_state = OPLOCK_STATE_NONE;
86888679
wake_up_interruptible_all(&opinfo->oplock_q);
86898680
atomic_dec(&opinfo->breaking_cnt);
86908681
wake_up_interruptible_all(&opinfo->oplock_brk);
8691-
86928682
opinfo_put(opinfo);
8693-
smb2_set_err_rsp(work);
86948683
}
86958684

86968685
/**

0 commit comments

Comments
 (0)