Skip to content

Commit

Permalink
net: hns3: fix race condition in debugfs
Browse files Browse the repository at this point in the history
When multiple threads concurrently access the debugfs content, data
and pointer exceptions may occur. Therefore, mutex lock protection is
added for debugfs.

Fixes: 5e69ea7 ("net: hns3: refactor the debugfs process")
Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yufeng Mo authored and David S. Miller committed Dec 12, 2021
1 parent 27cbf64 commit 6dde452
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,8 @@ struct hnae3_handle {

u8 netdev_flags;
struct dentry *hnae3_dbgfs;
/* protects concurrent contention between debugfs commands */
struct mutex dbgfs_lock;

/* Network interface message level enabled bits */
u32 msg_enable;
Expand Down
20 changes: 14 additions & 6 deletions drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
if (ret)
return ret;

mutex_lock(&handle->dbgfs_lock);
save_buf = &hns3_dbg_cmd[index].buf;

if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
Expand All @@ -1238,15 +1239,15 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
read_buf = *save_buf;
} else {
read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
if (!read_buf)
return -ENOMEM;
if (!read_buf) {
ret = -ENOMEM;
goto out;
}

/* save the buffer addr until the last read operation */
*save_buf = read_buf;
}

/* get data ready for the first time to read */
if (!*ppos) {
/* get data ready for the first time to read */
ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
read_buf, hns3_dbg_cmd[index].buf_len);
if (ret)
Expand All @@ -1255,8 +1256,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,

size = simple_read_from_buffer(buffer, count, ppos, read_buf,
strlen(read_buf));
if (size > 0)
if (size > 0) {
mutex_unlock(&handle->dbgfs_lock);
return size;
}

out:
/* free the buffer for the last read operation */
Expand All @@ -1265,6 +1268,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
*save_buf = NULL;
}

mutex_unlock(&handle->dbgfs_lock);
return ret;
}

Expand Down Expand Up @@ -1337,6 +1341,8 @@ int hns3_dbg_init(struct hnae3_handle *handle)
debugfs_create_dir(hns3_dbg_dentry[i].name,
handle->hnae3_dbgfs);

mutex_init(&handle->dbgfs_lock);

for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
Expand All @@ -1363,6 +1369,7 @@ int hns3_dbg_init(struct hnae3_handle *handle)
return 0;

out:
mutex_destroy(&handle->dbgfs_lock);
debugfs_remove_recursive(handle->hnae3_dbgfs);
handle->hnae3_dbgfs = NULL;
return ret;
Expand All @@ -1378,6 +1385,7 @@ void hns3_dbg_uninit(struct hnae3_handle *handle)
hns3_dbg_cmd[i].buf = NULL;
}

mutex_destroy(&handle->dbgfs_lock);
debugfs_remove_recursive(handle->hnae3_dbgfs);
handle->hnae3_dbgfs = NULL;
}
Expand Down

0 comments on commit 6dde452

Please sign in to comment.