From aae46585093942a27c1d386f25a0cf8c308130e7 Mon Sep 17 00:00:00 2001 From: Yufeng Mo Date: Fri, 31 Dec 2021 11:29:07 +0800 Subject: [PATCH] net: hns3: fix the concurrency between functions reading debugfs driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4OSRU CVE: NA ---------------------------- [1298504.847848] Call trace: [1298504.847859] [] dump_backtrace+0x0/0x23c [1298504.847865] [] show_stack+0x24/0x2c [1298504.847870] [] dump_stack+0x84/0xa8 [1298504.847878] [] bad_page+0xec/0x14c [1298504.847883] [] free_pages_check_bad+0x90/0x9c [1298504.847888] [] __free_pages_ok+0x2b8/0x2ec [1298504.847894] [] __free_pages+0x44/0x64 [1298504.847900] [] kfree+0x198/0x1a0 [1298504.847905] [] kvfree+0x3c/0x58 [1298504.847937] [] hns3_dbg_read+0xf4/0x278 [hns3] [1298504.847944] [] full_proxy_read+0x60/0x90 [1298504.847949] [] __vfs_read+0x58/0x178 [1298504.847952] [] vfs_read+0x90/0x14c [1298504.847956] [] SyS_read+0x60/0xc0 When different functions reading the same debugfs node, it will cause double free problem, because different functions shared the same node buffer. This patch make different functions have their own buffer to fix the problem. Fixes: 319ba0a4d154 ("net: hns3: fix race condition in debugfs") Fixes: c91910efc03a ("net: hns3: refactor the debugfs process") Signed-off-by: Yufeng Mo Signed-off-by: Yonglong Liu Reviewed-by: Jian Shen Signed-off-by: Yang Yingliang --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_debugfs.c | 15 +++++++++++---- .../net/ethernet/hisilicon/hns3/hns3_debugfs.h | 1 - 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 0d849c13f22f..61b92430e56d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -765,6 +765,7 @@ struct hnae3_handle { u8 netdev_flags; struct dentry *hnae3_dbgfs; struct mutex dbgfs_lock; + char **dbgfs_buf; /* Network interface message level enabled bits */ u32 msg_enable; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index c68e5f3d0ba5..8dbbf597d8a2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -808,7 +808,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, return ret; mutex_lock(&handle->dbgfs_lock); - save_buf = &hns3_dbg_cmd[index].buf; + save_buf = &handle->dbgfs_buf[index]; if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) || test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) { @@ -911,6 +911,13 @@ int hns3_dbg_init(struct hnae3_handle *handle) int ret; u32 i; + handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev, + ARRAY_SIZE(hns3_dbg_cmd), + sizeof(*handle->dbgfs_buf), + GFP_KERNEL); + if (!handle->dbgfs_buf) + return -ENOMEM; + hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry = debugfs_create_dir(name, hns3_dbgfs_root); handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry; @@ -952,9 +959,9 @@ void hns3_dbg_uninit(struct hnae3_handle *handle) u32 i; for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) - if (hns3_dbg_cmd[i].buf) { - kvfree(hns3_dbg_cmd[i].buf); - hns3_dbg_cmd[i].buf = NULL; + if (handle->dbgfs_buf[i]) { + kvfree(handle->dbgfs_buf[i]); + handle->dbgfs_buf[i] = NULL; } mutex_destroy(&handle->dbgfs_lock); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.h b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.h index ea65e5174ea9..902e16d99fb7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.h @@ -49,7 +49,6 @@ struct hns3_dbg_cmd_info { enum hnae3_dbg_cmd cmd; enum hns3_dbg_dentry_type dentry; u32 buf_len; - char *buf; int (*init)(struct hnae3_handle *handle, unsigned int cmd); }; -- GitLab