mirror of
https://github.com/samba-team/samba.git
synced 2025-01-21 18:04:06 +03:00
smbd: Fix channel sequence number checks for long-running requests
When the client's supplied csn overflows and hits a pending, long-running request's csn, we panic. Fix this by counting the overflows in smbXsrv_open_global0->channel_generation Bug: https://bugzilla.samba.org/show_bug.cgi?id=13215 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Volker Lendecke <vl@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> (cherry picked from commit 0b57434151a8334a6e9b9b7542824ce4915421a2)
This commit is contained in:
parent
c3bce29f1e
commit
082c08efb4
@ -430,7 +430,8 @@ interface smbXsrv
|
||||
uint32 durable_timeout_msec;
|
||||
boolean8 durable;
|
||||
DATA_BLOB backend_cookie;
|
||||
hyper channel_sequence;
|
||||
uint16 channel_sequence;
|
||||
hyper channel_generation;
|
||||
} smbXsrv_open_global0;
|
||||
|
||||
typedef union {
|
||||
|
@ -733,6 +733,7 @@ struct smbd_smb2_request {
|
||||
* adapted again in reply.
|
||||
*/
|
||||
bool request_counters_updated;
|
||||
uint64_t channel_generation;
|
||||
|
||||
/*
|
||||
* The sub request for async backend calls.
|
||||
|
@ -2141,6 +2141,7 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
|
||||
struct smbXsrv_connection *xconn = req->xconn;
|
||||
const uint8_t *inhdr;
|
||||
uint16_t channel_sequence;
|
||||
uint8_t generation_wrap = 0;
|
||||
uint32_t flags;
|
||||
int cmp;
|
||||
struct smbXsrv_open *op;
|
||||
@ -2167,6 +2168,14 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
|
||||
channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
|
||||
|
||||
cmp = channel_sequence - op->global->channel_sequence;
|
||||
if (cmp < 0) {
|
||||
/*
|
||||
* csn wrap. We need to watch out for long-running
|
||||
* requests that are still sitting on a previously
|
||||
* used csn. SMB2_OP_NOTIFY can take VERY long.
|
||||
*/
|
||||
generation_wrap += 1;
|
||||
}
|
||||
|
||||
if (abs(cmp) > INT16_MAX) {
|
||||
/*
|
||||
@ -2222,6 +2231,7 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
|
||||
op->pre_request_count += op->request_count;
|
||||
op->request_count = 1;
|
||||
op->global->channel_sequence = channel_sequence;
|
||||
op->global->channel_generation += generation_wrap;
|
||||
update_open = true;
|
||||
req->request_counters_updated = true;
|
||||
} else if (modify_call) {
|
||||
@ -2235,12 +2245,14 @@ static NTSTATUS smbd_smb2_request_dispatch_update_counts(
|
||||
op->pre_request_count += op->request_count;
|
||||
op->request_count = 1;
|
||||
op->global->channel_sequence = channel_sequence;
|
||||
op->global->channel_generation += generation_wrap;
|
||||
update_open = true;
|
||||
req->request_counters_updated = true;
|
||||
} else if (modify_call) {
|
||||
return NT_STATUS_FILE_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
req->channel_generation = op->global->channel_generation;
|
||||
|
||||
if (update_open) {
|
||||
status = smbXsrv_open_update(op);
|
||||
@ -2726,7 +2738,8 @@ static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
|
||||
inhdr = SMBD_SMB2_IN_HDR_PTR(req);
|
||||
channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
|
||||
|
||||
if (op->global->channel_sequence == channel_sequence) {
|
||||
if ((op->global->channel_sequence == channel_sequence) &&
|
||||
(op->global->channel_generation == req->channel_generation)) {
|
||||
SMB_ASSERT(op->request_count > 0);
|
||||
op->request_count -= 1;
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user