mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge tag 'v6.18-rc1-smb-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: - Fix RPC hang due to locking bug - Fix for memory leak in read and refcount leak (in session setup) - Minor cleanup * tag 'v6.18-rc1-smb-server-fixes' of git://git.samba.org/ksmbd: ksmbd: fix recursive locking in RPC handle list access smb/server: fix possible refcount leak in smb2_sess_setup() smb/server: fix possible memory leak in smb2_read() smb: server: Use common error handling code in smb_direct_rdma_xmit()
This commit is contained in:
@@ -147,14 +147,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
|
||||
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
|
||||
{
|
||||
struct ksmbd_session_rpc *entry;
|
||||
int method;
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
lockdep_assert_held(&sess->rpc_lock);
|
||||
entry = xa_load(&sess->rpc_handle_list, id);
|
||||
method = entry ? entry->method : 0;
|
||||
up_read(&sess->rpc_lock);
|
||||
|
||||
return method;
|
||||
return entry ? entry->method : 0;
|
||||
}
|
||||
|
||||
void ksmbd_session_destroy(struct ksmbd_session *sess)
|
||||
|
||||
@@ -1806,6 +1806,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
|
||||
if (ksmbd_conn_need_reconnect(conn)) {
|
||||
rc = -EFAULT;
|
||||
ksmbd_user_session_put(sess);
|
||||
sess = NULL;
|
||||
goto out_err;
|
||||
}
|
||||
@@ -4625,8 +4626,15 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
|
||||
* pipe without opening it, checking error condition here
|
||||
*/
|
||||
id = req->VolatileFileId;
|
||||
if (!ksmbd_session_rpc_method(sess, id))
|
||||
|
||||
lockdep_assert_not_held(&sess->rpc_lock);
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
if (!ksmbd_session_rpc_method(sess, id)) {
|
||||
up_read(&sess->rpc_lock);
|
||||
return -ENOENT;
|
||||
}
|
||||
up_read(&sess->rpc_lock);
|
||||
|
||||
ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
|
||||
req->FileInfoClass, req->VolatileFileId);
|
||||
@@ -6824,6 +6832,7 @@ int smb2_read(struct ksmbd_work *work)
|
||||
|
||||
nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf);
|
||||
if (nbytes < 0) {
|
||||
kvfree(aux_payload_buf);
|
||||
err = nbytes;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -825,6 +825,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
lockdep_assert_not_held(&sess->rpc_lock);
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
msg->type = KSMBD_EVENT_RPC_REQUEST;
|
||||
req = (struct ksmbd_rpc_command *)msg->payload;
|
||||
req->handle = handle;
|
||||
@@ -833,6 +836,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle
|
||||
req->flags |= KSMBD_RPC_WRITE_METHOD;
|
||||
req->payload_sz = payload_sz;
|
||||
memcpy(req->payload, payload, payload_sz);
|
||||
up_read(&sess->rpc_lock);
|
||||
|
||||
resp = ipc_msg_send_request(msg, req->handle);
|
||||
ipc_msg_free(msg);
|
||||
@@ -849,6 +853,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
lockdep_assert_not_held(&sess->rpc_lock);
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
msg->type = KSMBD_EVENT_RPC_REQUEST;
|
||||
req = (struct ksmbd_rpc_command *)msg->payload;
|
||||
req->handle = handle;
|
||||
@@ -856,6 +863,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
|
||||
req->flags |= rpc_context_flags(sess);
|
||||
req->flags |= KSMBD_RPC_READ_METHOD;
|
||||
req->payload_sz = 0;
|
||||
up_read(&sess->rpc_lock);
|
||||
|
||||
resp = ipc_msg_send_request(msg, req->handle);
|
||||
ipc_msg_free(msg);
|
||||
@@ -876,6 +884,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
lockdep_assert_not_held(&sess->rpc_lock);
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
msg->type = KSMBD_EVENT_RPC_REQUEST;
|
||||
req = (struct ksmbd_rpc_command *)msg->payload;
|
||||
req->handle = handle;
|
||||
@@ -884,6 +895,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle
|
||||
req->flags |= KSMBD_RPC_IOCTL_METHOD;
|
||||
req->payload_sz = payload_sz;
|
||||
memcpy(req->payload, payload, payload_sz);
|
||||
up_read(&sess->rpc_lock);
|
||||
|
||||
resp = ipc_msg_send_request(msg, req->handle);
|
||||
ipc_msg_free(msg);
|
||||
|
||||
@@ -1574,18 +1574,14 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
|
||||
get_buf_page_count(desc_buf, desc_buf_len),
|
||||
msg->sg_list, SG_CHUNK_SIZE);
|
||||
if (ret) {
|
||||
kfree(msg);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
goto free_msg;
|
||||
}
|
||||
|
||||
ret = get_sg_list(desc_buf, desc_buf_len,
|
||||
msg->sgt.sgl, msg->sgt.orig_nents);
|
||||
if (ret < 0) {
|
||||
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
|
||||
kfree(msg);
|
||||
goto out;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto free_table;
|
||||
|
||||
ret = rdma_rw_ctx_init(&msg->rdma_ctx, sc->ib.qp, sc->ib.qp->port,
|
||||
msg->sgt.sgl,
|
||||
@@ -1596,9 +1592,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
|
||||
is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to init rdma_rw_ctx: %d\n", ret);
|
||||
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
|
||||
kfree(msg);
|
||||
goto out;
|
||||
goto free_table;
|
||||
}
|
||||
|
||||
list_add_tail(&msg->list, &msg_list);
|
||||
@@ -1630,6 +1624,12 @@ out:
|
||||
atomic_add(credits_needed, &sc->rw_io.credits.count);
|
||||
wake_up(&sc->rw_io.credits.wait_queue);
|
||||
return ret;
|
||||
|
||||
free_table:
|
||||
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
|
||||
free_msg:
|
||||
kfree(msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int smb_direct_rdma_write(struct ksmbd_transport *t,
|
||||
|
||||
Reference in New Issue
Block a user