From: Namjae Jeon namjae.jeon@samsung.com
mainline inclusion from mainline-5.15-rc1 commit d40012a83f87f47967ad0b3c346179c7e5339ae7 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G CVE: NA
Reference: https://git.kernel.org/torvalds/linux/c/d40012a83f87
-------------------------------
Matthew pointed out that embedding struct ida into the struct is better than having a pointer to it. This patch initialise it statically using DEFINE_IDA() or ida_init() and remove ksmbd_ida_alloc/free().
Signed-off-by: Namjae Jeon namjae.jeon@samsung.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com --- fs/cifsd/connection.c | 3 +-- fs/cifsd/connection.h | 2 +- fs/cifsd/ksmbd_work.c | 2 +- fs/cifsd/mgmt/ksmbd_ida.c | 45 ++++++++++-------------------------- fs/cifsd/mgmt/ksmbd_ida.h | 17 ++++---------- fs/cifsd/mgmt/user_session.c | 29 +++++------------------ fs/cifsd/mgmt/user_session.h | 7 +----- fs/cifsd/server.c | 7 ------ fs/cifsd/smb2pdu.c | 4 ++-- fs/cifsd/transport_ipc.c | 34 +++++++++------------------ 10 files changed, 40 insertions(+), 110 deletions(-)
diff --git a/fs/cifsd/connection.c b/fs/cifsd/connection.c index e1814492fb58..4785dd59fcc5 100644 --- a/fs/cifsd/connection.c +++ b/fs/cifsd/connection.c @@ -38,7 +38,6 @@ void ksmbd_conn_free(struct ksmbd_conn *conn) write_unlock(&conn_list_lock);
kvfree(conn->request_buf); - ksmbd_ida_free(conn->async_ida); kfree(conn->preauth_info); kfree(conn); } @@ -70,7 +69,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) INIT_LIST_HEAD(&conn->async_requests); spin_lock_init(&conn->request_lock); spin_lock_init(&conn->credits_lock); - conn->async_ida = ksmbd_ida_alloc(); + ida_init(&conn->async_ida);
write_lock(&conn_list_lock); list_add(&conn->conns_list, &conn_list); diff --git a/fs/cifsd/connection.h b/fs/cifsd/connection.h index 021dada3d76d..00ede7a67199 100644 --- a/fs/cifsd/connection.h +++ b/fs/cifsd/connection.h @@ -101,7 +101,7 @@ struct ksmbd_conn { struct sockaddr_storage peer_addr;
/* Identifier for async message */ - struct ksmbd_ida *async_ida; + struct ida async_ida;
__le16 cipher_type; __le16 compress_algorithm; diff --git a/fs/cifsd/ksmbd_work.c b/fs/cifsd/ksmbd_work.c index 33ee52c1829f..eb8c8a34acab 100644 --- a/fs/cifsd/ksmbd_work.c +++ b/fs/cifsd/ksmbd_work.c @@ -53,7 +53,7 @@ void ksmbd_free_work_struct(struct ksmbd_work *work) kfree(work->tr_buf); kvfree(work->request_buf); if (work->async_id) - ksmbd_release_id(work->conn->async_ida, work->async_id); + ksmbd_release_id(&work->conn->async_ida, work->async_id); kmem_cache_free(work_cache, work); }
diff --git a/fs/cifsd/mgmt/ksmbd_ida.c b/fs/cifsd/mgmt/ksmbd_ida.c index cbc9fd049852..3dbc27cb5385 100644 --- a/fs/cifsd/mgmt/ksmbd_ida.c +++ b/fs/cifsd/mgmt/ksmbd_ida.c @@ -5,65 +5,44 @@
#include "ksmbd_ida.h"
-struct ksmbd_ida *ksmbd_ida_alloc(void) +static inline int __acquire_id(struct ida *ida, int from, int to) { - struct ksmbd_ida *ida; - - ida = kmalloc(sizeof(struct ksmbd_ida), GFP_KERNEL); - if (!ida) - return NULL; - - ida_init(&ida->map); - return ida; -} - -void ksmbd_ida_free(struct ksmbd_ida *ida) -{ - if (!ida) - return; - - ida_destroy(&ida->map); - kfree(ida); -} - -static inline int __acquire_id(struct ksmbd_ida *ida, int from, int to) -{ - return ida_simple_get(&ida->map, from, to, GFP_KERNEL); + return ida_simple_get(ida, from, to, GFP_KERNEL); }
-int ksmbd_acquire_smb2_tid(struct ksmbd_ida *ida) +int ksmbd_acquire_smb2_tid(struct ida *ida) { int id;
- do { + id = __acquire_id(ida, 0, 0); + if (id == 0xFFFF) id = __acquire_id(ida, 0, 0); - } while (id == 0xFFFF);
return id; }
-int ksmbd_acquire_smb2_uid(struct ksmbd_ida *ida) +int ksmbd_acquire_smb2_uid(struct ida *ida) { int id;
- do { + id = __acquire_id(ida, 1, 0); + if (id == 0xFFFE) id = __acquire_id(ida, 1, 0); - } while (id == 0xFFFE);
return id; }
-int ksmbd_acquire_async_msg_id(struct ksmbd_ida *ida) +int ksmbd_acquire_async_msg_id(struct ida *ida) { return __acquire_id(ida, 1, 0); }
-int ksmbd_acquire_id(struct ksmbd_ida *ida) +int ksmbd_acquire_id(struct ida *ida) { return __acquire_id(ida, 0, 0); }
-void ksmbd_release_id(struct ksmbd_ida *ida, int id) +void ksmbd_release_id(struct ida *ida, int id) { - ida_simple_remove(&ida->map, id); + ida_simple_remove(ida, id); } diff --git a/fs/cifsd/mgmt/ksmbd_ida.h b/fs/cifsd/mgmt/ksmbd_ida.h index b075156adf23..2bc07b16cfde 100644 --- a/fs/cifsd/mgmt/ksmbd_ida.h +++ b/fs/cifsd/mgmt/ksmbd_ida.h @@ -9,13 +9,6 @@ #include <linux/slab.h> #include <linux/idr.h>
-struct ksmbd_ida { - struct ida map; -}; - -struct ksmbd_ida *ksmbd_ida_alloc(void); -void ksmbd_ida_free(struct ksmbd_ida *ida); - /* * 2.2.1.6.7 TID Generation * The value 0xFFFF MUST NOT be used as a valid TID. All other @@ -23,7 +16,7 @@ void ksmbd_ida_free(struct ksmbd_ida *ida); * The value 0xFFFF is used to specify all TIDs or no TID, * depending upon the context in which it is used. */ -int ksmbd_acquire_smb2_tid(struct ksmbd_ida *ida); +int ksmbd_acquire_smb2_tid(struct ida *ida);
/* * 2.2.1.6.8 UID Generation @@ -32,10 +25,10 @@ int ksmbd_acquire_smb2_tid(struct ksmbd_ida *ida); * valid UID.<21> All other possible values for a UID, excluding * zero (0x0000), are valid. */ -int ksmbd_acquire_smb2_uid(struct ksmbd_ida *ida); -int ksmbd_acquire_async_msg_id(struct ksmbd_ida *ida); +int ksmbd_acquire_smb2_uid(struct ida *ida); +int ksmbd_acquire_async_msg_id(struct ida *ida);
-int ksmbd_acquire_id(struct ksmbd_ida *ida); +int ksmbd_acquire_id(struct ida *ida);
-void ksmbd_release_id(struct ksmbd_ida *ida, int id); +void ksmbd_release_id(struct ida *ida, int id); #endif /* __KSMBD_IDA_MANAGEMENT_H__ */ diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index 52c5c036ecf9..739588a6c96a 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -17,7 +17,7 @@ #include "../buffer_pool.h" #include "../vfs_cache.h"
-static struct ksmbd_ida *session_ida; +static DEFINE_IDA(session_ida);
#define SESSION_HASH_BITS 3 static DEFINE_HASHTABLE(sessions_table, SESSION_HASH_BITS); @@ -172,9 +172,7 @@ void ksmbd_session_destroy(struct ksmbd_session *sess) ksmbd_session_rpc_clear_list(sess); free_channel_list(sess); kfree(sess->Preauth_HashValue); - ksmbd_release_id(session_ida, sess->id); - - ksmbd_ida_free(sess->tree_conn_ida); + ksmbd_release_id(&session_ida, sess->id); kfree(sess); }
@@ -254,7 +252,7 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)
static int __init_smb2_session(struct ksmbd_session *sess) { - int id = ksmbd_acquire_smb2_uid(session_ida); + int id = ksmbd_acquire_smb2_uid(&session_ida);
if (id < 0) return -EINVAL; @@ -294,9 +292,7 @@ static struct ksmbd_session *__session_create(int protocol) if (ret) goto error;
- sess->tree_conn_ida = ksmbd_ida_alloc(); - if (!sess->tree_conn_ida) - goto error; + ida_init(&sess->tree_conn_ida);
if (protocol == CIFDS_SESSION_FLAG_SMB2) { down_write(&sessions_table_lock); @@ -320,7 +316,7 @@ int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess) int id = -EINVAL;
if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2)) - id = ksmbd_acquire_smb2_tid(sess->tree_conn_ida); + id = ksmbd_acquire_smb2_tid(&sess->tree_conn_ida);
return id; } @@ -328,18 +324,5 @@ int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess) void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id) { if (id >= 0) - ksmbd_release_id(sess->tree_conn_ida, id); -} - -int ksmbd_init_session_table(void) -{ - session_ida = ksmbd_ida_alloc(); - if (!session_ida) - return -ENOMEM; - return 0; -} - -void ksmbd_free_session_table(void) -{ - ksmbd_ida_free(session_ida); + ksmbd_release_id(&sess->tree_conn_ida, id); } diff --git a/fs/cifsd/mgmt/user_session.h b/fs/cifsd/mgmt/user_session.h index ad5c0430b62a..72b40348bdc4 100644 --- a/fs/cifsd/mgmt/user_session.h +++ b/fs/cifsd/mgmt/user_session.h @@ -16,7 +16,6 @@
#define PREAUTH_HASHVALUE_SIZE 64
-struct ksmbd_ida; struct ksmbd_file_table;
struct channel { @@ -52,7 +51,7 @@ struct ksmbd_session { struct hlist_node hlist; struct list_head ksmbd_chann_list; struct xarray tree_conns; - struct ksmbd_ida *tree_conn_ida; + struct ida tree_conn_ida; struct list_head rpc_handle_list;
@@ -101,8 +100,4 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id); int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id); int get_session(struct ksmbd_session *sess); void put_session(struct ksmbd_session *sess); - -int ksmbd_init_session_table(void); -void ksmbd_free_session_table(void); - #endif /* __USER_SESSION_MANAGEMENT_H__ */ diff --git a/fs/cifsd/server.c b/fs/cifsd/server.c index 04f959a88a1a..4aff89ce1464 100644 --- a/fs/cifsd/server.c +++ b/fs/cifsd/server.c @@ -537,7 +537,6 @@ static int ksmbd_server_shutdown(void) ksmbd_workqueue_destroy(); ksmbd_ipc_release(); ksmbd_conn_transport_destroy(); - ksmbd_free_session_table(); ksmbd_crypto_destroy(); ksmbd_free_global_file_table(); destroy_lease_table(NULL); @@ -566,10 +565,6 @@ static int __init ksmbd_server_init(void) if (ret) goto err_unregister;
- ret = ksmbd_init_session_table(); - if (ret) - goto err_destroy_pools; - ret = ksmbd_ipc_init(); if (ret) goto err_free_session_table; @@ -600,8 +595,6 @@ static int __init ksmbd_server_init(void) err_ipc_release: ksmbd_ipc_release(); err_free_session_table: - ksmbd_free_session_table(); -err_destroy_pools: ksmbd_destroy_buffer_pools(); err_unregister: class_unregister(&ksmbd_control_class); diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index c1f6361603b9..cc4e8f11c487 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -517,7 +517,7 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
work->syncronous = true; if (work->async_id) { - ksmbd_release_id(conn->async_ida, work->async_id); + ksmbd_release_id(&conn->async_ida, work->async_id); work->async_id = 0; }
@@ -685,7 +685,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) rsp_hdr = work->response_buf; rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND;
- id = ksmbd_acquire_async_msg_id(conn->async_ida); + id = ksmbd_acquire_async_msg_id(&conn->async_ida); if (id < 0) { ksmbd_err("Failed to alloc async message id\n"); return id; diff --git a/fs/cifsd/transport_ipc.c b/fs/cifsd/transport_ipc.c index 60c0289402c1..78061fecf816 100644 --- a/fs/cifsd/transport_ipc.c +++ b/fs/cifsd/transport_ipc.c @@ -35,7 +35,7 @@ static DEFINE_HASHTABLE(ipc_msg_table, IPC_MSG_HASH_BITS); static DECLARE_RWSEM(ipc_msg_table_lock); static DEFINE_MUTEX(startup_lock);
-static struct ksmbd_ida *ida; +static DEFINE_IDA(ipc_ida);
static unsigned int ksmbd_tools_pid;
@@ -247,7 +247,7 @@ static void ipc_msg_free(struct ksmbd_ipc_msg *msg) static void ipc_msg_handle_free(int handle) { if (handle >= 0) - ksmbd_release_id(ida, handle); + ksmbd_release_id(&ipc_ida, handle); }
static int handle_response(int type, void *payload, size_t sz) @@ -512,7 +512,7 @@ struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account)
msg->type = KSMBD_EVENT_LOGIN_REQUEST; req = KSMBD_IPC_MSG_PAYLOAD(msg); - req->handle = ksmbd_acquire_id(ida); + req->handle = ksmbd_acquire_id(&ipc_ida); strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
resp = ipc_msg_send_request(msg, req->handle); @@ -535,7 +535,7 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len)
msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST; req = KSMBD_IPC_MSG_PAYLOAD(msg); - req->handle = ksmbd_acquire_id(ida); + req->handle = ksmbd_acquire_id(&ipc_ida); req->spnego_blob_len = blob_len; memcpy(req->spnego_blob, spnego_blob, blob_len);
@@ -568,7 +568,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST; req = KSMBD_IPC_MSG_PAYLOAD(msg);
- req->handle = ksmbd_acquire_id(ida); + req->handle = ksmbd_acquire_id(&ipc_ida); req->account_flags = sess->user->flags; req->session_id = sess->id; req->connect_id = tree_conn->id; @@ -646,7 +646,7 @@ ksmbd_ipc_share_config_request(const char *name)
msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST; req = KSMBD_IPC_MSG_PAYLOAD(msg); - req->handle = ksmbd_acquire_id(ida); + req->handle = ksmbd_acquire_id(&ipc_ida); strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME);
resp = ipc_msg_send_request(msg, req->handle); @@ -785,7 +785,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payloa
msg->type = KSMBD_EVENT_RPC_REQUEST; req = KSMBD_IPC_MSG_PAYLOAD(msg); - req->handle = ksmbd_acquire_id(ida); + req->handle = ksmbd_acquire_id(&ipc_ida); req->flags = rpc_context_flags(sess); req->flags |= KSMBD_RPC_RAP_METHOD; req->payload_sz = payload_sz; @@ -842,18 +842,17 @@ static void ipc_timer_heartbeat(struct work_struct *w)
int ksmbd_ipc_id_alloc(void) { - return ksmbd_acquire_id(ida); + return ksmbd_acquire_id(&ipc_ida); }
void ksmbd_rpc_id_free(int handle) { - ksmbd_release_id(ida, handle); + ksmbd_release_id(&ipc_ida, handle); }
void ksmbd_ipc_release(void) { cancel_delayed_work_sync(&ipc_timer_work); - ksmbd_ida_free(ida); genl_unregister_family(&ksmbd_genl_family); }
@@ -867,7 +866,7 @@ void ksmbd_ipc_soft_reset(void)
int ksmbd_ipc_init(void) { - int ret; + int ret = 0;
ksmbd_nl_init_fixup(); INIT_DELAYED_WORK(&ipc_timer_work, ipc_timer_heartbeat); @@ -875,19 +874,8 @@ int ksmbd_ipc_init(void) ret = genl_register_family(&ksmbd_genl_family); if (ret) { ksmbd_err("Failed to register KSMBD netlink interface %d\n", ret); - goto cancel_work; + cancel_delayed_work_sync(&ipc_timer_work); }
- ida = ksmbd_ida_alloc(); - if (!ida) { - ret = -ENOMEM; - goto unregister; - } - return 0; - -unregister: - genl_unregister_family(&ksmbd_genl_family); -cancel_work: - cancel_delayed_work_sync(&ipc_timer_work); return ret; }