summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-30 10:06:56 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-30 10:06:56 -0800
commit109daa2356efe73491e32a3b2431c8bf57a6c58e (patch)
treecbe7cfa34fdb9b4e5cb60ab9aebe489b914e3bc6
parentd8b78066f4c9c8ec898bd4246fc4db31d476dd88 (diff)
parent9a8c5d89d327ff58e9b2517f8a6afb4181d32c6e (diff)
downloadlinux-109daa2356efe73491e32a3b2431c8bf57a6c58e.tar.gz
linux-109daa2356efe73491e32a3b2431c8bf57a6c58e.tar.bz2
linux-109daa2356efe73491e32a3b2431c8bf57a6c58e.zip
Merge tag '6.13-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull smb server updates from Steve French: - fix use after free due to race in ksmd workqueue handler - debugging improvements - fix incorrectly formatted response when client attempts SMB1 - improve memory allocation to reduce chance of OOM - improve delays between retries when killing sessions * tag '6.13-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: fix use-after-free in SMB request handling ksmbd: add debug print for pending request during server shutdown ksmbd: add netdev-up/down event debug print ksmbd: add debug prints to know what smb2 requests were received ksmbd: add debug print for rdma capable ksmbd: use msleep instaed of schedule_timeout_interruptible() ksmbd: use __GFP_RETRY_MAYFAIL ksmbd: fix malformed unsupported smb1 negotiate response
-rw-r--r--fs/smb/server/asn1.c6
-rw-r--r--fs/smb/server/auth.c19
-rw-r--r--fs/smb/server/connection.c7
-rw-r--r--fs/smb/server/crypto_ctx.c6
-rw-r--r--fs/smb/server/glob.h2
-rw-r--r--fs/smb/server/ksmbd_work.c10
-rw-r--r--fs/smb/server/mgmt/ksmbd_ida.c11
-rw-r--r--fs/smb/server/mgmt/share_config.c10
-rw-r--r--fs/smb/server/mgmt/tree_connect.c5
-rw-r--r--fs/smb/server/mgmt/user_config.c8
-rw-r--r--fs/smb/server/mgmt/user_session.c10
-rw-r--r--fs/smb/server/misc.c11
-rw-r--r--fs/smb/server/ndr.c10
-rw-r--r--fs/smb/server/oplock.c12
-rw-r--r--fs/smb/server/server.c8
-rw-r--r--fs/smb/server/smb2pdu.c76
-rw-r--r--fs/smb/server/smb_common.c4
-rw-r--r--fs/smb/server/smbacl.c23
-rw-r--r--fs/smb/server/transport_ipc.c6
-rw-r--r--fs/smb/server/transport_rdma.c13
-rw-r--r--fs/smb/server/transport_tcp.c18
-rw-r--r--fs/smb/server/unicode.c4
-rw-r--r--fs/smb/server/vfs.c12
-rw-r--r--fs/smb/server/vfs_cache.c10
24 files changed, 171 insertions, 130 deletions
diff --git a/fs/smb/server/asn1.c b/fs/smb/server/asn1.c
index b931a99ab9c8..5c4c5121fece 100644
--- a/fs/smb/server/asn1.c
+++ b/fs/smb/server/asn1.c
@@ -104,7 +104,7 @@ int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
oid_len + ntlmssp_len) * 2 +
neg_result_len + oid_len + ntlmssp_len;
- buf = kmalloc(total_len, GFP_KERNEL);
+ buf = kmalloc(total_len, KSMBD_DEFAULT_GFP);
if (!buf)
return -ENOMEM;
@@ -140,7 +140,7 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
int total_len = 4 + compute_asn_hdr_len_bytes(neg_result_len) * 2 +
neg_result_len;
- buf = kmalloc(total_len, GFP_KERNEL);
+ buf = kmalloc(total_len, KSMBD_DEFAULT_GFP);
if (!buf)
return -ENOMEM;
@@ -217,7 +217,7 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
if (!vlen)
return -EINVAL;
- conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
+ conn->mechToken = kmemdup_nul(value, vlen, KSMBD_DEFAULT_GFP);
if (!conn->mechToken)
return -ENOMEM;
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index 611716bc8f27..1d1ffd0acaca 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -151,7 +151,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
/* convert user_name to unicode */
len = strlen(user_name(sess->user));
- uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
+ uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
if (!uniname) {
ret = -ENOMEM;
goto out;
@@ -175,7 +175,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
/* Convert domain name or conn name to unicode and uppercase */
len = strlen(dname);
- domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
+ domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
if (!domain) {
ret = -ENOMEM;
goto out;
@@ -254,7 +254,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
}
len = CIFS_CRYPTO_KEY_SIZE + blen;
- construct = kzalloc(len, GFP_KERNEL);
+ construct = kzalloc(len, KSMBD_DEFAULT_GFP);
if (!construct) {
rc = -ENOMEM;
goto out;
@@ -361,7 +361,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
if (sess_key_len > CIFS_KEY_SIZE)
return -EINVAL;
- ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
+ ctx_arc4 = kmalloc(sizeof(*ctx_arc4), KSMBD_DEFAULT_GFP);
if (!ctx_arc4)
return -ENOMEM;
@@ -451,7 +451,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
chgblob->NegotiateFlags = cpu_to_le32(flags);
len = strlen(ksmbd_netbios_name());
- name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
+ name = kmalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
if (!name)
return -ENOMEM;
@@ -1043,7 +1043,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
if (!nvec)
return NULL;
- nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL);
+ nr_entries = kcalloc(nvec, sizeof(int), KSMBD_DEFAULT_GFP);
if (!nr_entries)
return NULL;
@@ -1063,7 +1063,8 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
/* Add two entries for transform header and signature */
total_entries += 2;
- sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
+ sg = kmalloc_array(total_entries, sizeof(struct scatterlist),
+ KSMBD_DEFAULT_GFP);
if (!sg) {
kfree(nr_entries);
return NULL;
@@ -1163,7 +1164,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
goto free_ctx;
}
- req = aead_request_alloc(tfm, GFP_KERNEL);
+ req = aead_request_alloc(tfm, KSMBD_DEFAULT_GFP);
if (!req) {
rc = -ENOMEM;
goto free_ctx;
@@ -1182,7 +1183,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
}
iv_len = crypto_aead_ivsize(tfm);
- iv = kzalloc(iv_len, GFP_KERNEL);
+ iv = kzalloc(iv_len, KSMBD_DEFAULT_GFP);
if (!iv) {
rc = -ENOMEM;
goto free_sg;
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index e6a72f75ab94..c14dd72e1b30 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -52,7 +52,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
{
struct ksmbd_conn *conn;
- conn = kzalloc(sizeof(struct ksmbd_conn), GFP_KERNEL);
+ conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP);
if (!conn)
return NULL;
@@ -359,7 +359,7 @@ int ksmbd_conn_handler_loop(void *p)
/* 4 for rfc1002 length field */
/* 1 for implied bcc[0] */
size = pdu_size + 4 + 1;
- conn->request_buf = kvmalloc(size, GFP_KERNEL);
+ conn->request_buf = kvmalloc(size, KSMBD_DEFAULT_GFP);
if (!conn->request_buf)
break;
@@ -404,6 +404,7 @@ int ksmbd_conn_handler_loop(void *p)
out:
ksmbd_conn_set_releasing(conn);
/* Wait till all reference dropped to the Server object*/
+ ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count));
wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);
if (IS_ENABLED(CONFIG_UNICODE))
@@ -462,7 +463,7 @@ again:
up_read(&conn_list_lock);
if (!list_empty(&conn_list)) {
- schedule_timeout_interruptible(HZ / 10); /* 100ms */
+ msleep(100);
goto again;
}
}
diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c
index 81488d04199d..ce733dc9a4a3 100644
--- a/fs/smb/server/crypto_ctx.c
+++ b/fs/smb/server/crypto_ctx.c
@@ -89,7 +89,7 @@ static struct shash_desc *alloc_shash_desc(int id)
return NULL;
shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (!shash)
crypto_free_shash(tfm);
else
@@ -133,7 +133,7 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void)
ctx_list.avail_ctx++;
spin_unlock(&ctx_list.ctx_lock);
- ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL);
+ ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP);
if (!ctx) {
spin_lock(&ctx_list.ctx_lock);
ctx_list.avail_ctx--;
@@ -258,7 +258,7 @@ int ksmbd_crypto_create(void)
init_waitqueue_head(&ctx_list.ctx_wait);
ctx_list.avail_ctx = 1;
- ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL);
+ ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP);
if (!ctx)
return -ENOMEM;
list_add(&ctx->list, &ctx_list.idle_ctx);
diff --git a/fs/smb/server/glob.h b/fs/smb/server/glob.h
index d528b20b37a8..4ea187af2348 100644
--- a/fs/smb/server/glob.h
+++ b/fs/smb/server/glob.h
@@ -44,4 +44,6 @@ extern int ksmbd_debug_types;
#define UNICODE_LEN(x) ((x) * 2)
+#define KSMBD_DEFAULT_GFP (GFP_KERNEL | __GFP_RETRY_MAYFAIL)
+
#endif /* __KSMBD_GLOB_H */
diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c
index d7c676c151e2..4af2e6007c29 100644
--- a/fs/smb/server/ksmbd_work.c
+++ b/fs/smb/server/ksmbd_work.c
@@ -18,7 +18,7 @@ static struct workqueue_struct *ksmbd_wq;
struct ksmbd_work *ksmbd_alloc_work_struct(void)
{
- struct ksmbd_work *work = kmem_cache_zalloc(work_cache, GFP_KERNEL);
+ struct ksmbd_work *work = kmem_cache_zalloc(work_cache, KSMBD_DEFAULT_GFP);
if (work) {
work->compound_fid = KSMBD_NO_FID;
@@ -30,7 +30,7 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void)
INIT_LIST_HEAD(&work->aux_read_list);
work->iov_alloc_cnt = 4;
work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec),
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (!work->iov) {
kmem_cache_free(work_cache, work);
work = NULL;
@@ -114,7 +114,7 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
if (aux_size) {
need_iov_cnt++;
- ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
+ ar = kmalloc(sizeof(struct aux_read), KSMBD_DEFAULT_GFP);
if (!ar)
return -ENOMEM;
}
@@ -125,7 +125,7 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
work->iov_alloc_cnt += 4;
new = krealloc(work->iov,
sizeof(struct kvec) * work->iov_alloc_cnt,
- GFP_KERNEL | __GFP_ZERO);
+ KSMBD_DEFAULT_GFP | __GFP_ZERO);
if (!new) {
kfree(ar);
work->iov_alloc_cnt -= 4;
@@ -169,7 +169,7 @@ int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len,
int allocate_interim_rsp_buf(struct ksmbd_work *work)
{
- work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL);
+ work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, KSMBD_DEFAULT_GFP);
if (!work->response_buf)
return -ENOMEM;
work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
diff --git a/fs/smb/server/mgmt/ksmbd_ida.c b/fs/smb/server/mgmt/ksmbd_ida.c
index a18e27e9e0cd..0e2ae994ab52 100644
--- a/fs/smb/server/mgmt/ksmbd_ida.c
+++ b/fs/smb/server/mgmt/ksmbd_ida.c
@@ -4,31 +4,32 @@
*/
#include "ksmbd_ida.h"
+#include "../glob.h"
int ksmbd_acquire_smb2_tid(struct ida *ida)
{
- return ida_alloc_range(ida, 1, 0xFFFFFFFE, GFP_KERNEL);
+ return ida_alloc_range(ida, 1, 0xFFFFFFFE, KSMBD_DEFAULT_GFP);
}
int ksmbd_acquire_smb2_uid(struct ida *ida)
{
int id;
- id = ida_alloc_min(ida, 1, GFP_KERNEL);
+ id = ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP);
if (id == 0xFFFE)
- id = ida_alloc_min(ida, 1, GFP_KERNEL);
+ id = ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP);
return id;
}
int ksmbd_acquire_async_msg_id(struct ida *ida)
{
- return ida_alloc_min(ida, 1, GFP_KERNEL);
+ return ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP);
}
int ksmbd_acquire_id(struct ida *ida)
{
- return ida_alloc(ida, GFP_KERNEL);
+ return ida_alloc(ida, KSMBD_DEFAULT_GFP);
}
void ksmbd_release_id(struct ida *ida, int id)
diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c
index d8d03070ae44..d3d5f99bdd34 100644
--- a/fs/smb/server/mgmt/share_config.c
+++ b/fs/smb/server/mgmt/share_config.c
@@ -102,11 +102,11 @@ static int parse_veto_list(struct ksmbd_share_config *share,
if (!sz)
break;
- p = kzalloc(sizeof(struct ksmbd_veto_pattern), GFP_KERNEL);
+ p = kzalloc(sizeof(struct ksmbd_veto_pattern), KSMBD_DEFAULT_GFP);
if (!p)
return -ENOMEM;
- p->pattern = kstrdup(veto_list, GFP_KERNEL);
+ p->pattern = kstrdup(veto_list, KSMBD_DEFAULT_GFP);
if (!p->pattern) {
kfree(p);
return -ENOMEM;
@@ -150,14 +150,14 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
goto out;
}
- share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL);
+ share = kzalloc(sizeof(struct ksmbd_share_config), KSMBD_DEFAULT_GFP);
if (!share)
goto out;
share->flags = resp->flags;
atomic_set(&share->refcount, 1);
INIT_LIST_HEAD(&share->veto_list);
- share->name = kstrdup(name, GFP_KERNEL);
+ share->name = kstrdup(name, KSMBD_DEFAULT_GFP);
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
int path_len = PATH_MAX;
@@ -166,7 +166,7 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
path_len = resp->payload_sz - resp->veto_list_sz;
share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (share->path) {
share->path_sz = strlen(share->path);
while (share->path_sz > 1 &&
diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c
index 94a52a75014a..ecfc57508671 100644
--- a/fs/smb/server/mgmt/tree_connect.c
+++ b/fs/smb/server/mgmt/tree_connect.c
@@ -31,7 +31,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
if (!sc)
return status;
- tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), GFP_KERNEL);
+ tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect),
+ KSMBD_DEFAULT_GFP);
if (!tree_conn) {
status.ret = -ENOMEM;
goto out_error;
@@ -80,7 +81,7 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
init_waitqueue_head(&tree_conn->refcount_q);
ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn,
- GFP_KERNEL));
+ KSMBD_DEFAULT_GFP));
if (ret) {
status.ret = -ENOMEM;
goto out_error;
diff --git a/fs/smb/server/mgmt/user_config.c b/fs/smb/server/mgmt/user_config.c
index 421a4a95e216..56c9a38ca878 100644
--- a/fs/smb/server/mgmt/user_config.c
+++ b/fs/smb/server/mgmt/user_config.c
@@ -36,16 +36,16 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
{
struct ksmbd_user *user;
- user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL);
+ user = kmalloc(sizeof(struct ksmbd_user), KSMBD_DEFAULT_GFP);
if (!user)
return NULL;
- user->name = kstrdup(resp->account, GFP_KERNEL);
+ user->name = kstrdup(resp->account, KSMBD_DEFAULT_GFP);
user->flags = resp->status;
user->gid = resp->gid;
user->uid = resp->uid;
user->passkey_sz = resp->hash_sz;
- user->passkey = kmalloc(resp->hash_sz, GFP_KERNEL);
+ user->passkey = kmalloc(resp->hash_sz, KSMBD_DEFAULT_GFP);
if (user->passkey)
memcpy(user->passkey, resp->hash, resp->hash_sz);
@@ -64,7 +64,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
user->sgid = kmemdup(resp_ext->____payload,
resp_ext->ngroups * sizeof(gid_t),
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (!user->sgid)
goto err_free;
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index ad02fe555fda..df92d746e89c 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -98,7 +98,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
if (!method)
return -EINVAL;
- entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL);
+ entry = kzalloc(sizeof(struct ksmbd_session_rpc), KSMBD_DEFAULT_GFP);
if (!entry)
return -ENOMEM;
@@ -106,7 +106,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
entry->id = ksmbd_ipc_id_alloc();
if (entry->id < 0)
goto free_entry;
- old = xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
+ old = xa_store(&sess->rpc_handle_list, entry->id, entry, KSMBD_DEFAULT_GFP);
if (xa_is_err(old))
goto free_id;
@@ -201,7 +201,7 @@ int ksmbd_session_register(struct ksmbd_conn *conn,
sess->dialect = conn->dialect;
memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
ksmbd_expire_session(conn);
- return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL));
+ return xa_err(xa_store(&conn->sessions, sess->id, sess, KSMBD_DEFAULT_GFP));
}
static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
@@ -314,7 +314,7 @@ struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
{
struct preauth_session *sess;
- sess = kmalloc(sizeof(struct preauth_session), GFP_KERNEL);
+ sess = kmalloc(sizeof(struct preauth_session), KSMBD_DEFAULT_GFP);
if (!sess)
return NULL;
@@ -398,7 +398,7 @@ static struct ksmbd_session *__session_create(int protocol)
if (protocol != CIFDS_SESSION_FLAG_SMB2)
return NULL;
- sess = kzalloc(sizeof(struct ksmbd_session), GFP_KERNEL);
+ sess = kzalloc(sizeof(struct ksmbd_session), KSMBD_DEFAULT_GFP);
if (!sess)
return NULL;
diff --git a/fs/smb/server/misc.c b/fs/smb/server/misc.c
index 1a5faa6f6e7b..cb2a11ffb23f 100644
--- a/fs/smb/server/misc.c
+++ b/fs/smb/server/misc.c
@@ -165,7 +165,7 @@ char *convert_to_nt_pathname(struct ksmbd_share_config *share,
char *pathname, *ab_pathname, *nt_pathname;
int share_path_len = share->path_sz;
- pathname = kmalloc(PATH_MAX, GFP_KERNEL);
+ pathname = kmalloc(PATH_MAX, KSMBD_DEFAULT_GFP);
if (!pathname)
return ERR_PTR(-EACCES);
@@ -180,7 +180,8 @@ char *convert_to_nt_pathname(struct ksmbd_share_config *share,
goto free_pathname;
}
- nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 2, GFP_KERNEL);
+ nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 2,
+ KSMBD_DEFAULT_GFP);
if (!nt_pathname) {
nt_pathname = ERR_PTR(-ENOMEM);
goto free_pathname;
@@ -232,7 +233,7 @@ char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name)
char *cf_name;
int cf_len;
- cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, GFP_KERNEL);
+ cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, KSMBD_DEFAULT_GFP);
if (!cf_name)
return ERR_PTR(-ENOMEM);
@@ -294,7 +295,7 @@ char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name)
path_len = share->path_sz;
name_len = strlen(name);
- new_name = kmalloc(path_len + name_len + 2, GFP_KERNEL);
+ new_name = kmalloc(path_len + name_len + 2, KSMBD_DEFAULT_GFP);
if (!new_name)
return new_name;
@@ -320,7 +321,7 @@ char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info,
if (!sz)
return NULL;
- conv = kmalloc(sz, GFP_KERNEL);
+ conv = kmalloc(sz, KSMBD_DEFAULT_GFP);
if (!conv)
return NULL;
diff --git a/fs/smb/server/ndr.c b/fs/smb/server/ndr.c
index 3507d8f89074..58d71560f626 100644
--- a/fs/smb/server/ndr.c
+++ b/fs/smb/server/ndr.c
@@ -18,7 +18,7 @@ static int try_to_realloc_ndr_blob(struct ndr *n, size_t sz)
{
char *data;
- data = krealloc(n->data, n->offset + sz + 1024, GFP_KERNEL);
+ data = krealloc(n->data, n->offset + sz + 1024, KSMBD_DEFAULT_GFP);
if (!data)
return -ENOMEM;
@@ -174,7 +174,7 @@ int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
n->offset = 0;
n->length = 1024;
- n->data = kzalloc(n->length, GFP_KERNEL);
+ n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP);
if (!n->data)
return -ENOMEM;
@@ -350,7 +350,7 @@ int ndr_encode_posix_acl(struct ndr *n,
n->offset = 0;
n->length = 1024;
- n->data = kzalloc(n->length, GFP_KERNEL);
+ n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP);
if (!n->data)
return -ENOMEM;
@@ -401,7 +401,7 @@ int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
n->offset = 0;
n->length = 2048;
- n->data = kzalloc(n->length, GFP_KERNEL);
+ n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP);
if (!n->data)
return -ENOMEM;
@@ -505,7 +505,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
return ret;
acl->sd_size = n->length - n->offset;
- acl->sd_buf = kzalloc(acl->sd_size, GFP_KERNEL);
+ acl->sd_buf = kzalloc(acl->sd_size, KSMBD_DEFAULT_GFP);
if (!acl->sd_buf)
return -ENOMEM;
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 4142c7ad5fa9..3a3fe4afbdf0 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -34,7 +34,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
struct ksmbd_session *sess = work->sess;
struct oplock_info *opinfo;
- opinfo = kzalloc(sizeof(struct oplock_info), GFP_KERNEL);
+ opinfo = kzalloc(sizeof(struct oplock_info), KSMBD_DEFAULT_GFP);
if (!opinfo)
return NULL;
@@ -94,7 +94,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx)
{
struct lease *lease;
- lease = kmalloc(sizeof(struct lease), GFP_KERNEL);
+ lease = kmalloc(sizeof(struct lease), KSMBD_DEFAULT_GFP);
if (!lease)
return -ENOMEM;
@@ -709,7 +709,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
if (!work)
return -ENOMEM;
- br_info = kmalloc(sizeof(struct oplock_break_info), GFP_KERNEL);
+ br_info = kmalloc(sizeof(struct oplock_break_info), KSMBD_DEFAULT_GFP);
if (!br_info) {
ksmbd_free_work_struct(work);
return -ENOMEM;
@@ -812,7 +812,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
if (!work)
return -ENOMEM;
- br_info = kmalloc(sizeof(struct lease_break_info), GFP_KERNEL);
+ br_info = kmalloc(sizeof(struct lease_break_info), KSMBD_DEFAULT_GFP);
if (!br_info) {
ksmbd_free_work_struct(work);
return -ENOMEM;
@@ -1057,7 +1057,7 @@ static int add_lease_global_list(struct oplock_info *opinfo)
}
read_unlock(&lease_list_lock);
- lb = kmalloc(sizeof(struct lease_table), GFP_KERNEL);
+ lb = kmalloc(sizeof(struct lease_table), KSMBD_DEFAULT_GFP);
if (!lb)
return -ENOMEM;
@@ -1499,7 +1499,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
if (IS_ERR_OR_NULL(cc))
return NULL;
- lreq = kzalloc(sizeof(struct lease_ctx_info), GFP_KERNEL);
+ lreq = kzalloc(sizeof(struct lease_ctx_info), KSMBD_DEFAULT_GFP);
if (!lreq)
return NULL;
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index e6cfedba9992..930d7566b52e 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -47,7 +47,7 @@ static int ___server_conf_set(int idx, char *val)
return -EINVAL;
kfree(server_conf.conf[idx]);
- server_conf.conf[idx] = kstrdup(val, GFP_KERNEL);
+ server_conf.conf[idx] = kstrdup(val, KSMBD_DEFAULT_GFP);
if (!server_conf.conf[idx])
return -ENOMEM;
return 0;
@@ -276,8 +276,12 @@ static void handle_ksmbd_work(struct work_struct *wk)
* disconnection. waitqueue_active is safe because it
* uses atomic operation for condition.
*/
+ atomic_inc(&conn->refcnt);
if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
wake_up(&conn->r_count_q);
+
+ if (atomic_dec_and_test(&conn->refcnt))
+ kfree(conn);
}
/**
@@ -415,7 +419,7 @@ static int __queue_ctrl_work(int type)
{
struct server_ctrl_struct *ctrl;
- ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL);
+ ctrl = kmalloc(sizeof(struct server_ctrl_struct), KSMBD_DEFAULT_GFP);
if (!ctrl)
return -ENOMEM;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 599118aed205..416f7df4edef 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -551,7 +551,7 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
if (le32_to_cpu(hdr->NextCommand) > 0)
sz = large_sz;
- work->response_buf = kvzalloc(sz, GFP_KERNEL);
+ work->response_buf = kvzalloc(sz, KSMBD_DEFAULT_GFP);
if (!work->response_buf)
return -ENOMEM;
@@ -1147,7 +1147,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
case SMB311_PROT_ID:
conn->preauth_info =
kzalloc(sizeof(struct preauth_integrity_info),
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (!conn->preauth_info) {
rc = -ENOMEM;
rsp->hdr.Status = STATUS_INVALID_PARAMETER;
@@ -1266,7 +1266,7 @@ static int alloc_preauth_hash(struct ksmbd_session *sess,
return 0;
sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue,
- PREAUTH_HASHVALUE_SIZE, GFP_KERNEL);
+ PREAUTH_HASHVALUE_SIZE, KSMBD_DEFAULT_GFP);
if (!sess->Preauth_HashValue)
return -ENOMEM;
@@ -1352,7 +1352,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
sz = sizeof(struct challenge_message);
sz += (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6;
- neg_blob = kzalloc(sz, GFP_KERNEL);
+ neg_blob = kzalloc(sz, KSMBD_DEFAULT_GFP);
if (!neg_blob)
return -ENOMEM;
@@ -1543,12 +1543,12 @@ binding_session:
if (conn->dialect >= SMB30_PROT_ID) {
chann = lookup_chann_list(sess, conn);
if (!chann) {
- chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
+ chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP);
if (!chann)
return -ENOMEM;
chann->conn = conn;
- xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP);
}
}
@@ -1624,12 +1624,12 @@ static int krb5_authenticate(struct ksmbd_work *work,
if (conn->dialect >= SMB30_PROT_ID) {
chann = lookup_chann_list(sess, conn);
if (!chann) {
- chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
+ chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP);
if (!chann)
return -ENOMEM;
chann->conn = conn;
- xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP);
}
}
@@ -1666,7 +1666,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
unsigned int negblob_len, negblob_off;
int rc = 0;
- ksmbd_debug(SMB, "Received request for session setup\n");
+ ksmbd_debug(SMB, "Received smb2 session setup request\n");
WORK_BUFFERS(work, req, rsp);
@@ -1940,6 +1940,8 @@ int smb2_tree_connect(struct ksmbd_work *work)
struct ksmbd_share_config *share = NULL;
int rc = -EINVAL;
+ ksmbd_debug(SMB, "Received smb2 tree connect request\n");
+
WORK_BUFFERS(work, req, rsp);
treename = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->PathOffset),
@@ -2136,9 +2138,9 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
struct ksmbd_tree_connect *tcon = work->tcon;
int err;
- WORK_BUFFERS(work, req, rsp);
+ ksmbd_debug(SMB, "Received smb2 tree disconnect request\n");
- ksmbd_debug(SMB, "request\n");
+ WORK_BUFFERS(work, req, rsp);
if (!tcon) {
ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
@@ -2203,7 +2205,7 @@ int smb2_session_logoff(struct ksmbd_work *work)
WORK_BUFFERS(work, req, rsp);
- ksmbd_debug(SMB, "request\n");
+ ksmbd_debug(SMB, "Received smb2 session logoff request\n");
ksmbd_conn_lock(conn);
if (!ksmbd_conn_good(conn)) {
@@ -2346,7 +2348,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
le16_to_cpu(eabuf->EaValueLength))
return -EINVAL;
- attr_name = kmalloc(XATTR_NAME_MAX + 1, GFP_KERNEL);
+ attr_name = kmalloc(XATTR_NAME_MAX + 1, KSMBD_DEFAULT_GFP);
if (!attr_name)
return -ENOMEM;
@@ -2849,6 +2851,8 @@ int smb2_open(struct ksmbd_work *work)
__le32 daccess, maximal_access = 0;
int iov_len = 0;
+ ksmbd_debug(SMB, "Received smb2 create request\n");
+
WORK_BUFFERS(work, req, rsp);
if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
@@ -2897,7 +2901,7 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2;
}
} else {
- name = kstrdup("", GFP_KERNEL);
+ name = kstrdup("", KSMBD_DEFAULT_GFP);
if (!name) {
rc = -ENOMEM;
goto err_out2;
@@ -3338,7 +3342,7 @@ int smb2_open(struct ksmbd_work *work)
sizeof(struct smb_sid) * 3 +
sizeof(struct smb_acl) +
sizeof(struct smb_ace) * ace_num * 2,
- GFP_KERNEL);
+ KSMBD_DEFAULT_GFP);
if (!pntsd) {
posix_acl_release(fattr.cf_acls);
posix_acl_release(fattr.cf_dacls);
@@ -4296,6 +4300,8 @@ int smb2_query_dir(struct ksmbd_work *work)
int buffer_sz;
struct smb2_query_dir_private query_dir_private = {NULL, };
+ ksmbd_debug(SMB, "Received smb2 query directory request\n");
+
WORK_BUFFERS(work, req, rsp);
if (ksmbd_override_fsids(work)) {
@@ -4946,7 +4952,7 @@ static int get_file_stream_info(struct ksmbd_work *work,
/* plus : size */
streamlen += 1;
- stream_buf = kmalloc(streamlen + 1, GFP_KERNEL);
+ stream_buf = kmalloc(streamlen + 1, KSMBD_DEFAULT_GFP);
if (!stream_buf)
break;
@@ -5602,9 +5608,9 @@ int smb2_query_info(struct ksmbd_work *work)
struct smb2_query_info_rsp *rsp;
int rc = 0;
- WORK_BUFFERS(work