Skip to content

Commit e38ec88

Browse files
namjaejeongregkh
authored andcommitted
ksmbd: fix potential use-after-free in oplock/lease break ack
commit 50f930db22365738d9387c974416f38a06e8057e 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 <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 595f78d commit e38ec88

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
@@ -8144,28 +8144,22 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
81448144
goto err_out;
81458145
}
81468146

8147-
opinfo->op_state = OPLOCK_STATE_NONE;
8148-
wake_up_interruptible_all(&opinfo->oplock_q);
8149-
opinfo_put(opinfo);
8150-
ksmbd_fd_put(work, fp);
8151-
81528147
rsp->StructureSize = cpu_to_le16(24);
81538148
rsp->OplockLevel = rsp_oplevel;
81548149
rsp->Reserved = 0;
81558150
rsp->Reserved2 = 0;
81568151
rsp->VolatileFid = volatile_id;
81578152
rsp->PersistentFid = persistent_id;
81588153
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8159-
if (!ret)
8160-
return;
8161-
8154+
if (ret) {
81628155
err_out:
8156+
smb2_set_err_rsp(work);
8157+
}
8158+
81638159
opinfo->op_state = OPLOCK_STATE_NONE;
81648160
wake_up_interruptible_all(&opinfo->oplock_q);
8165-
81668161
opinfo_put(opinfo);
81678162
ksmbd_fd_put(work, fp);
8168-
smb2_set_err_rsp(work);
81698163
}
81708164

81718165
static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -8295,11 +8289,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
82958289
}
82968290

82978291
lease_state = lease->state;
8298-
opinfo->op_state = OPLOCK_STATE_NONE;
8299-
wake_up_interruptible_all(&opinfo->oplock_q);
8300-
atomic_dec(&opinfo->breaking_cnt);
8301-
wake_up_interruptible_all(&opinfo->oplock_brk);
8302-
opinfo_put(opinfo);
83038292

83048293
rsp->StructureSize = cpu_to_le16(36);
83058294
rsp->Reserved = 0;
@@ -8308,16 +8297,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
83088297
rsp->LeaseState = lease_state;
83098298
rsp->LeaseDuration = 0;
83108299
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8311-
if (!ret)
8312-
return;
8313-
8300+
if (ret) {
83148301
err_out:
8302+
smb2_set_err_rsp(work);
8303+
}
8304+
8305+
opinfo->op_state = OPLOCK_STATE_NONE;
83158306
wake_up_interruptible_all(&opinfo->oplock_q);
83168307
atomic_dec(&opinfo->breaking_cnt);
83178308
wake_up_interruptible_all(&opinfo->oplock_brk);
8318-
83198309
opinfo_put(opinfo);
8320-
smb2_set_err_rsp(work);
83218310
}
83228311

83238312
/**

0 commit comments

Comments
 (0)