summaryrefslogtreecommitdiff
path: root/fs/ksmbd
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2021-12-31 03:26:25 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-01-27 13:02:53 +0300
commitd7004f0cc4a739e315f620773392b8d867993fe8 (patch)
tree69f80c30dc27b25c3951f38387abac407e64175d /fs/ksmbd
parent0aadd32bebc9506b1fc88ab43c6174c2e371ad7b (diff)
downloadlinux-d7004f0cc4a739e315f620773392b8d867993fe8.tar.xz
ksmbd: limits exceeding the maximum allowable outstanding requests
commit b589f5db6d4af8f14d70e31e1276b4c017668a26 upstream. If the client ignores the CreditResponse received from the server and continues to send the request, ksmbd limits the requests if it exceeds smb2 max credits. 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>
Diffstat (limited to 'fs/ksmbd')
-rw-r--r--fs/ksmbd/connection.c1
-rw-r--r--fs/ksmbd/connection.h3
-rw-r--r--fs/ksmbd/smb2misc.c9
-rw-r--r--fs/ksmbd/smb2pdu.c1
4 files changed, 13 insertions, 1 deletions
diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
index b57a0d8a392f..f7d5e8b7bef7 100644
--- a/fs/ksmbd/connection.c
+++ b/fs/ksmbd/connection.c
@@ -62,6 +62,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
atomic_set(&conn->req_running, 0);
atomic_set(&conn->r_count, 0);
conn->total_credits = 1;
+ conn->outstanding_credits = 1;
init_waitqueue_head(&conn->req_running_q);
INIT_LIST_HEAD(&conn->conns_list);
diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h
index 08e85568ccd6..8694aef482c1 100644
--- a/fs/ksmbd/connection.h
+++ b/fs/ksmbd/connection.h
@@ -61,7 +61,8 @@ struct ksmbd_conn {
atomic_t req_running;
/* References which are made for this Server object*/
atomic_t r_count;
- unsigned short total_credits;
+ unsigned int total_credits;
+ unsigned int outstanding_credits;
spinlock_t credits_lock;
wait_queue_head_t req_running_q;
/* Lock to protect requests list*/
diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c
index e4a28eae51b2..cc1c38686ecd 100644
--- a/fs/ksmbd/smb2misc.c
+++ b/fs/ksmbd/smb2misc.c
@@ -338,7 +338,16 @@ static int smb2_validate_credit_charge(struct ksmbd_conn *conn,
credit_charge, conn->total_credits);
ret = 1;
}
+
+ if ((u64)conn->outstanding_credits + credit_charge > conn->vals->max_credits) {
+ ksmbd_debug(SMB, "Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n",
+ credit_charge, conn->outstanding_credits);
+ ret = 1;
+ } else
+ conn->outstanding_credits += credit_charge;
+
spin_unlock(&conn->credits_lock);
+
return ret;
}
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 1d9eb7873452..f694ee10a0bc 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -324,6 +324,7 @@ int smb2_set_rsp_credits(struct ksmbd_work *work)
}
conn->total_credits -= credit_charge;
+ conn->outstanding_credits -= credit_charge;
credits_requested = max_t(unsigned short,
le16_to_cpu(req_hdr->CreditRequest), 1);