From 9b424fbe748154d8ceb161ce126d5d7331c82797 Mon Sep 17 00:00:00 2001 From: Wen Chen Date: Wed, 10 Dec 2025 10:07:54 +0800 Subject: [PATCH] urma: fixed process exiting uburma driver's private memory UAF urma inclusion category: bugfix bugzilla: https://gitee.com/openeuler/release-management/issues/ID3WJX ---------------------------------------------- 1. This patch primarily modifies uburma private resource management and logging (DFX). The implementation provides the following key functionalities: 1. Modifies the opening, releasing, and unmapping of uburma umap. 2. Modifies the default warning in ubcm logging; adds log level settings to ubcore. 3. Supports write atomic semantics. Fixes: c25f37d4e464 ("urma: bugfix ubagg drivers refent error") Signed-off-by: Wen Chen --- drivers/ub/urma/ubcore/ubcm/ubcm_log.c | 2 +- drivers/ub/urma/ubcore/ubcm/ubmad_datapath.c | 24 +++--- drivers/ub/urma/ubcore/ubcore_main.c | 6 +- drivers/ub/urma/uburma/uburma_mmap.c | 82 +++++++------------- include/ub/urma/ubcore_opcode.h | 1 + include/ub/urma/ubcore_types.h | 6 +- 6 files changed, 53 insertions(+), 68 deletions(-) diff --git a/drivers/ub/urma/ubcore/ubcm/ubcm_log.c b/drivers/ub/urma/ubcore/ubcm/ubcm_log.c index dd0154308276..1d462e4e632b 100644 --- a/drivers/ub/urma/ubcore/ubcm/ubcm_log.c +++ b/drivers/ub/urma/ubcore/ubcm/ubcm_log.c @@ -12,4 +12,4 @@ #include #include "ubcm_log.h" -uint32_t g_ubcm_log_level = UBCM_LOG_LEVEL_INFO; +uint32_t g_ubcm_log_level = UBCM_LOG_LEVEL_WARNING; diff --git a/drivers/ub/urma/ubcore/ubcm/ubmad_datapath.c b/drivers/ub/urma/ubcore/ubcm/ubmad_datapath.c index e6897e29c62c..e0e45948a8de 100644 --- a/drivers/ub/urma/ubcore/ubcm/ubmad_datapath.c +++ b/drivers/ub/urma/ubcore/ubcm/ubmad_datapath.c @@ -121,7 +121,7 @@ static void ubmad_rt_work_handler(struct work_struct *work) ubcm_log_err("repost send failed. msg type %d msn %llu\n", msg->msg_type, msg->msn); } - ubcm_log_info("Do not repost, found: %u, rt_work->rt_cnt: %u.\n", + ubcm_log_info_rl("Do not repost, found: %u, rt_work->rt_cnt: %u.\n", (uint32_t)found, rt_work->rt_cnt); /* not found OR repost failed @@ -369,7 +369,7 @@ static int ubmad_do_post_send_conn_data(struct ubcore_jetty *jetty, goto destroy_msn_node; } - ubcm_log_info("send conn data successfully. msn %llu eid " EID_FMT "\n", + ubcm_log_info_rl("send conn data successfully. msn %llu eid " EID_FMT "\n", msn, EID_ARGS(*dst_eid)); return 0; @@ -587,7 +587,7 @@ int ubmad_repost_send_conn_data(struct ubcore_jetty *jetty, return -1; } - ubcm_log_info("send conn data successfully. msn %llu eid " EID_FMT "\n", + ubcm_log_info_rl("send conn data successfully. msn %llu eid " EID_FMT "\n", msn, EID_ARGS(*dst_eid)); return 0; } @@ -603,7 +603,7 @@ int ubmad_repost_send(struct ubmad_msg *msg, struct ubmad_tjetty *tjetty, struct ubcore_jfs_wr jfs_wr = { 0 }; int ret; - ubcm_log_info("timeout and repost. msn %llu eid " EID_FMT "\n", + ubcm_log_info_rl("timeout and repost. msn %llu eid " EID_FMT "\n", msg->msn, EID_ARGS(*dst_eid)); // prepare wr @@ -802,7 +802,7 @@ static int ubmad_process_conn_data(struct ubcore_cr *cr, } } - ubcm_log_info( + ubcm_log_info_rl( "Finish to recv request. msn %llu right_end %llu, seid " EID_FMT "\n", msg->msn, seid_node->rx_bitmap->right_end, EID_ARGS(*seid)); @@ -854,12 +854,12 @@ static void ubmad_process_conn_ack(struct ubcore_cr *cr, } spin_unlock_irqrestore(&msn_mgr->msn_hlist_lock, flag); // msn_node not in msn_hlist, indicates already removed by previous ack with same msn - ubcm_log_info("redundant ack. msn %llu seid " EID_FMT "\n", msg->msn, + ubcm_log_info_rl("redundant ack. msn %llu seid " EID_FMT "\n", msg->msn, EID_ARGS(*seid)); put_tjetty: ubmad_put_tjetty(tjetty); - ubcm_log_info("recv conn ack. msn %llu seid " EID_FMT "\n", msg->msn, + ubcm_log_info_rl("recv conn ack. msn %llu seid " EID_FMT "\n", msg->msn, EID_ARGS(*seid)); } @@ -887,7 +887,7 @@ static inline void ubmad_process_close_req(struct ubcore_cr *cr, ubmad_remove_tjetty(&cr->remote_id.eid, rsrc); ubmad_delete_seid_node(&cr->remote_id.eid, rsrc); - ubcm_log_info("Finish to process close request, remote eid: " EID_FMT + ubcm_log_info_rl("Finish to process close request, remote eid: " EID_FMT ", remote id: %u.\n", EID_ARGS(cr->remote_id.eid), cr->remote_id.id); } @@ -965,7 +965,7 @@ int ubmad_ubc_send(struct ubcore_device *device, send_buf->src_eid = dev_priv->eid_info.eid; ubmad_put_device_priv(dev_priv); - ubcm_log_info("ubc dev: %s, s_eid: " EID_FMT ", d_eid: " EID_FMT " ", + ubcm_log_info_rl("ubc dev: %s, s_eid: " EID_FMT ", d_eid: " EID_FMT " ", device->dev_name, EID_ARGS(send_buf->src_eid), EID_ARGS(send_buf->dst_eid)); @@ -1043,7 +1043,7 @@ static void ubmad_send_work_handler(struct ubmad_device_priv *dev_priv, } while (cr_cnt > 0); ret = ubcore_rearm_jfc(jfc, false); - ubcm_log_info("Rearm send jfc, jfc_id: %u, ret: %d.\n", jfc->id, ret); + ubcm_log_info_rl("Rearm send jfc, jfc_id: %u, ret: %d.\n", jfc->id, ret); } // polling here indicates if recv msg @@ -1106,7 +1106,7 @@ static void ubmad_recv_work_handler(struct ubmad_device_priv *dev_priv, } while (cr_cnt > 0); ret = ubcore_rearm_jfc(jfc, false); - ubcm_log_info("Rearm recv jfc, jfc_id: %u, ret: %d.\n", jfc->id, ret); + ubcm_log_info_rl("Rearm recv jfc, jfc_id: %u, ret: %d.\n", jfc->id, ret); } // continue from ubmad_jfce_handler() @@ -1164,7 +1164,7 @@ static void ubmad_jfce_handler(struct ubcore_jfc *jfc, jfc->ub_dev->dev_name); return; } - ubcm_log_info("Start to handle jfce, type: %d, jfc_id: %u.\n", type, jfc->id); + ubcm_log_info_rl("Start to handle jfce, type: %d, jfc_id: %u.\n", type, jfc->id); // free in ubmad_jfce_work_handler() jfce_work = kzalloc(sizeof(struct ubmad_jfce_work), GFP_ATOMIC); diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index b0cb2ca68823..2d090829e947 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -10,7 +10,6 @@ */ #include - #include "ubcore_main.h" #include "ubcore_log.h" #include "ubcore_workqueue.h" @@ -21,6 +20,11 @@ #include "ubcore_genl.h" #include "ubcm/ub_cm.h" +#define UBCORE_LOG_FILE_PERMISSION (0644) + +module_param(g_ubcore_log_level, uint, UBCORE_LOG_FILE_PERMISSION); +MODULE_PARM_DESC(g_ubcore_log_level, " 3: ERR, 4: WARNING, 6: INFO, 7: DEBUG"); + static int __init ubcore_init(void) { int ret; diff --git a/drivers/ub/urma/uburma/uburma_mmap.c b/drivers/ub/urma/uburma/uburma_mmap.c index c9ce4439b7a7..090fe4a05653 100644 --- a/drivers/ub/urma/uburma/uburma_mmap.c +++ b/drivers/ub/urma/uburma/uburma_mmap.c @@ -33,54 +33,43 @@ void uburma_umap_priv_init(struct uburma_umap_priv *priv, void uburma_unmap_vma_pages(struct uburma_file *ufile) { struct uburma_umap_priv *priv, *next_priv; - struct mm_struct *mm; + struct mm_struct *mm = NULL; + struct vm_area_struct *vma; int ret; if (list_empty(&ufile->umaps_list)) return; lockdep_assert_held(&ufile->cleanup_rwsem); - while (1) { - struct list_head local_list; - INIT_LIST_HEAD(&local_list); + while (1) { mm = NULL; mutex_lock(&ufile->umap_mutex); list_for_each_entry_safe(priv, next_priv, &ufile->umaps_list, node) { - struct mm_struct *curr_mm = priv->vma->vm_mm; - ret = mmget_not_zero(curr_mm); + mm = priv->vma->vm_mm; + ret = mmget_not_zero(mm); if (!ret) { list_del_init(&priv->node); + mm = NULL; continue; } - if (!mm) { - mm = curr_mm; - list_move_tail(&priv->node, &local_list); - } else if (curr_mm == mm) { - list_move_tail(&priv->node, &local_list); - } + break; } mutex_unlock(&ufile->umap_mutex); - - if (list_empty(&local_list)) { - if (mm) - mmput(mm); + if (!mm) return; - } mmap_read_lock(mm); - - list_for_each_entry_safe(priv, next_priv, &local_list, node) { - struct vm_area_struct *vma = priv->vma; - + mutex_lock(&ufile->umap_mutex); + list_for_each_entry_safe(priv, next_priv, &ufile->umaps_list, node) { + vma = priv->vma; + if (vma->vm_mm != mm) + continue; list_del_init(&priv->node); - if (vma->vm_mm == mm) { - vma->vm_private_data = NULL; - zap_vma_ptes(vma, vma->vm_start, - vma->vm_end - vma->vm_start); - } + zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start); } + mutex_unlock(&ufile->umap_mutex); mmap_read_unlock(mm); mmput(mm); @@ -114,18 +103,14 @@ static void uburma_umap_open(struct vm_area_struct *vma) static void uburma_umap_close(struct vm_area_struct *vma) { struct uburma_file *ufile = vma->vm_file->private_data; - struct uburma_umap_priv *next_priv = NULL; - struct uburma_umap_priv *priv = NULL; + struct uburma_umap_priv *priv = vma->vm_private_data; + + if (!priv) + return; mutex_lock(&ufile->umap_mutex); - list_for_each_entry_safe(priv, next_priv, &ufile->umaps_list, node) { - if (priv->vma == vma) { - list_del_init(&priv->node); - break; - } - } + list_del(&priv->node); mutex_unlock(&ufile->umap_mutex); - kfree(priv); vma->vm_private_data = NULL; } @@ -134,9 +119,9 @@ static vm_fault_t uburma_umap_fault(struct vm_fault *vmf) { struct uburma_file *ufile = vmf->vma->vm_file->private_data; struct uburma_umap_priv *priv = vmf->vma->vm_private_data; - struct page *page; + vm_fault_t ret = 0; - if (unlikely(!priv)) + if (!priv) return VM_FAULT_SIGBUS; if (!(vmf->vma->vm_flags & (VM_WRITE | VM_MAYWRITE))) { @@ -145,26 +130,19 @@ static vm_fault_t uburma_umap_fault(struct vm_fault *vmf) return 0; } - page = READ_ONCE(ufile->fault_page); - if (likely(page)) { - vmf->page = page; - get_page(vmf->page); - return 0; - } - mutex_lock(&ufile->umap_mutex); - if (!ufile->fault_page) { + if (!ufile->fault_page) ufile->fault_page = alloc_pages(vmf->gfp_mask | __GFP_ZERO, 0); - if (!ufile->fault_page) { - mutex_unlock(&ufile->umap_mutex); - return VM_FAULT_SIGBUS; - } + + if (ufile->fault_page) { + vmf->page = ufile->fault_page; + get_page(vmf->page); + } else { + ret = VM_FAULT_SIGBUS; } - vmf->page = ufile->fault_page; - get_page(vmf->page); mutex_unlock(&ufile->umap_mutex); - return 0; + return ret; } static const struct vm_operations_struct g_urma_umap_ops = { diff --git a/include/ub/urma/ubcore_opcode.h b/include/ub/urma/ubcore_opcode.h index d02bcd0d467d..583d4f85f8ff 100644 --- a/include/ub/urma/ubcore_opcode.h +++ b/include/ub/urma/ubcore_opcode.h @@ -72,6 +72,7 @@ enum ubcore_opcode { UBCORE_OPC_SEND_INVALIDATE = 0x42, // remote JFR/jetty ID and seg token id UBCORE_OPC_NOP = 0x51, + UBCORE_OPC_WRITE_ATOMIC = 0x60, UBCORE_OPC_LAST }; diff --git a/include/ub/urma/ubcore_types.h b/include/ub/urma/ubcore_types.h index b2563d84cb5c..8aa1306ee321 100644 --- a/include/ub/urma/ubcore_types.h +++ b/include/ub/urma/ubcore_types.h @@ -218,7 +218,8 @@ union ubcore_jfs_flag { /* (0x3): OL, low layer ordering */ /* (0x4): UNO, unreliable non ordering */ uint32_t multi_path : 1; - uint32_t reserved : 20; + uint32_t ctp_rc_mul_path_mode : 1; + uint32_t reserved : 19; } bs; uint32_t value; }; @@ -1344,7 +1345,8 @@ union ubcore_jetty_flag { /* (0x3): OL, low layer ordering */ /* (0x4): UNO, unreliable non ordering */ uint32_t multi_path : 1; - uint32_t reserved : 19; + uint32_t ctp_rc_mul_path_mode : 1; + uint32_t reserved : 18; } bs; uint32_t value; }; -- Gitee