Skip to content

Commit 0329cf1

Browse files
committed
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. Signed-off-by: Namjae Jeon <[email protected]>
1 parent be1dbb0 commit 0329cf1

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

smb2pdu.c

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

9178-
opinfo->op_state = OPLOCK_STATE_NONE;
9179-
wake_up_interruptible_all(&opinfo->oplock_q);
9180-
opinfo_put(opinfo);
9181-
ksmbd_fd_put(work, fp);
9182-
91839178
rsp->StructureSize = cpu_to_le16(24);
91849179
rsp->OplockLevel = rsp_oplevel;
91859180
rsp->Reserved = 0;
91869181
rsp->Reserved2 = 0;
91879182
rsp->VolatileFid = volatile_id;
91889183
rsp->PersistentFid = persistent_id;
91899184
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
9190-
if (!ret)
9191-
return;
9192-
9185+
if (ret) {
91939186
err_out:
9187+
smb2_set_err_rsp(work);
9188+
}
9189+
91949190
opinfo->op_state = OPLOCK_STATE_NONE;
91959191
wake_up_interruptible_all(&opinfo->oplock_q);
9196-
91979192
opinfo_put(opinfo);
91989193
ksmbd_fd_put(work, fp);
9199-
smb2_set_err_rsp(work);
92009194
}
92019195

92029196
static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -9326,11 +9320,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
93269320
}
93279321

93289322
lease_state = lease->state;
9329-
opinfo->op_state = OPLOCK_STATE_NONE;
9330-
wake_up_interruptible_all(&opinfo->oplock_q);
9331-
atomic_dec(&opinfo->breaking_cnt);
9332-
wake_up_interruptible_all(&opinfo->oplock_brk);
9333-
opinfo_put(opinfo);
93349323

93359324
rsp->StructureSize = cpu_to_le16(36);
93369325
rsp->Reserved = 0;
@@ -9339,16 +9328,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
93399328
rsp->LeaseState = lease_state;
93409329
rsp->LeaseDuration = 0;
93419330
ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
9342-
if (!ret)
9343-
return;
9344-
9331+
if (ret) {
93459332
err_out:
9333+
smb2_set_err_rsp(work);
9334+
}
9335+
9336+
opinfo->op_state = OPLOCK_STATE_NONE;
93469337
wake_up_interruptible_all(&opinfo->oplock_q);
93479338
atomic_dec(&opinfo->breaking_cnt);
93489339
wake_up_interruptible_all(&opinfo->oplock_brk);
9349-
93509340
opinfo_put(opinfo);
9351-
smb2_set_err_rsp(work);
93529341
}
93539342

93549343
/**

0 commit comments

Comments
 (0)