Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+34 -16
+2 -5
fs/smb/server/mgmt/user_session.c
··· 147 147 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) 148 148 { 149 149 struct ksmbd_session_rpc *entry; 150 - int method; 151 150 152 - down_read(&sess->rpc_lock); 151 + lockdep_assert_held(&sess->rpc_lock); 153 152 entry = xa_load(&sess->rpc_handle_list, id); 154 - method = entry ? entry->method : 0; 155 - up_read(&sess->rpc_lock); 156 153 157 - return method; 154 + return entry ? entry->method : 0; 158 155 } 159 156 160 157 void ksmbd_session_destroy(struct ksmbd_session *sess)
+10 -1
fs/smb/server/smb2pdu.c
··· 1806 1806 1807 1807 if (ksmbd_conn_need_reconnect(conn)) { 1808 1808 rc = -EFAULT; 1809 + ksmbd_user_session_put(sess); 1809 1810 sess = NULL; 1810 1811 goto out_err; 1811 1812 } ··· 4626 4625 * pipe without opening it, checking error condition here 4627 4626 */ 4628 4627 id = req->VolatileFileId; 4629 - if (!ksmbd_session_rpc_method(sess, id)) 4628 + 4629 + lockdep_assert_not_held(&sess->rpc_lock); 4630 + 4631 + down_read(&sess->rpc_lock); 4632 + if (!ksmbd_session_rpc_method(sess, id)) { 4633 + up_read(&sess->rpc_lock); 4630 4634 return -ENOENT; 4635 + } 4636 + up_read(&sess->rpc_lock); 4631 4637 4632 4638 ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n", 4633 4639 req->FileInfoClass, req->VolatileFileId); ··· 6832 6824 6833 6825 nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf); 6834 6826 if (nbytes < 0) { 6827 + kvfree(aux_payload_buf); 6835 6828 err = nbytes; 6836 6829 goto out; 6837 6830 }
+12
fs/smb/server/transport_ipc.c
··· 825 825 if (!msg) 826 826 return NULL; 827 827 828 + lockdep_assert_not_held(&sess->rpc_lock); 829 + 830 + down_read(&sess->rpc_lock); 828 831 msg->type = KSMBD_EVENT_RPC_REQUEST; 829 832 req = (struct ksmbd_rpc_command *)msg->payload; 830 833 req->handle = handle; ··· 836 833 req->flags |= KSMBD_RPC_WRITE_METHOD; 837 834 req->payload_sz = payload_sz; 838 835 memcpy(req->payload, payload, payload_sz); 836 + up_read(&sess->rpc_lock); 839 837 840 838 resp = ipc_msg_send_request(msg, req->handle); 841 839 ipc_msg_free(msg); ··· 853 849 if (!msg) 854 850 return NULL; 855 851 852 + lockdep_assert_not_held(&sess->rpc_lock); 853 + 854 + down_read(&sess->rpc_lock); 856 855 msg->type = KSMBD_EVENT_RPC_REQUEST; 857 856 req = (struct ksmbd_rpc_command *)msg->payload; 858 857 req->handle = handle; ··· 863 856 req->flags |= rpc_context_flags(sess); 864 857 req->flags |= KSMBD_RPC_READ_METHOD; 865 858 req->payload_sz = 0; 859 + up_read(&sess->rpc_lock); 866 860 867 861 resp = ipc_msg_send_request(msg, req->handle); 868 862 ipc_msg_free(msg); ··· 884 876 if (!msg) 885 877 return NULL; 886 878 879 + lockdep_assert_not_held(&sess->rpc_lock); 880 + 881 + down_read(&sess->rpc_lock); 887 882 msg->type = KSMBD_EVENT_RPC_REQUEST; 888 883 req = (struct ksmbd_rpc_command *)msg->payload; 889 884 req->handle = handle; ··· 895 884 req->flags |= KSMBD_RPC_IOCTL_METHOD; 896 885 req->payload_sz = payload_sz; 897 886 memcpy(req->payload, payload, payload_sz); 887 + up_read(&sess->rpc_lock); 898 888 899 889 resp = ipc_msg_send_request(msg, req->handle); 900 890 ipc_msg_free(msg);
+10 -10
fs/smb/server/transport_rdma.c
··· 1574 1574 get_buf_page_count(desc_buf, desc_buf_len), 1575 1575 msg->sg_list, SG_CHUNK_SIZE); 1576 1576 if (ret) { 1577 - kfree(msg); 1578 1577 ret = -ENOMEM; 1579 - goto out; 1578 + goto free_msg; 1580 1579 } 1581 1580 1582 1581 ret = get_sg_list(desc_buf, desc_buf_len, 1583 1582 msg->sgt.sgl, msg->sgt.orig_nents); 1584 - if (ret < 0) { 1585 - sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1586 - kfree(msg); 1587 - goto out; 1588 - } 1583 + if (ret < 0) 1584 + goto free_table; 1589 1585 1590 1586 ret = rdma_rw_ctx_init(&msg->rdma_ctx, sc->ib.qp, sc->ib.qp->port, 1591 1587 msg->sgt.sgl, ··· 1592 1596 is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); 1593 1597 if (ret < 0) { 1594 1598 pr_err("failed to init rdma_rw_ctx: %d\n", ret); 1595 - sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1596 - kfree(msg); 1597 - goto out; 1599 + goto free_table; 1598 1600 } 1599 1601 1600 1602 list_add_tail(&msg->list, &msg_list); ··· 1624 1630 atomic_add(credits_needed, &sc->rw_io.credits.count); 1625 1631 wake_up(&sc->rw_io.credits.wait_queue); 1626 1632 return ret; 1633 + 1634 + free_table: 1635 + sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); 1636 + free_msg: 1637 + kfree(msg); 1638 + goto out; 1627 1639 } 1628 1640 1629 1641 static int smb_direct_rdma_write(struct ksmbd_transport *t,