提交 541af4f8 编写于 作者: H Huajingjing 提交者: Jialin Zhang

Huawei BMA: Fix iBMA driver bug

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I67J42
CVE: NA

-------------------------------------------------

The BMA software is a system management software offered by Huawei.
It supports the status monitoring, performance monitoring and
event monitoring of various components, including server CPUs,
memory hard disks, NICs, IB cards, PCIe cards,
RAID controller cards and optical modules.

In this version, the system resets due to the BMA spin lock
when the memory usage is too high, the vulnerability has been rectified.
Signed-off-by: NHuajingjing <huajingjing1@huawei.com>
Reviewed-by: NChenJiesong <chenjiesong@huawei.com>
Signed-off-by: NJialin Zhang <zhangjialin11@huawei.com>
上级 355f87a3
......@@ -28,7 +28,7 @@
#ifdef DRV_VERSION
#define CDEV_VERSION MICRO_TO_STR(DRV_VERSION)
#else
#define CDEV_VERSION "0.3.4"
#define CDEV_VERSION "0.3.5"
#endif
#define CDEV_DEFAULT_NUM 4
......
......@@ -419,8 +419,10 @@ EXPORT_SYMBOL(bma_intf_int_to_bmc);
int bma_intf_is_link_ok(void)
{
return (g_bma_dev->edma_host.statistics.remote_status ==
REGISTERED) ? 1 : 0;
if ((&g_bma_dev->edma_host != NULL) &&
(g_bma_dev->edma_host.statistics.remote_status == REGISTERED))
return 1;
return 0;
}
EXPORT_SYMBOL(bma_intf_is_link_ok);
......@@ -460,14 +462,10 @@ int bma_cdev_recv_msg(void *handle, char __user *data, size_t count)
}
EXPORT_SYMBOL_GPL(bma_cdev_recv_msg);
int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
static int check_cdev_add_msg_param(struct bma_priv_data_s *handle,
const char __user *msg, size_t msg_len)
{
struct bma_priv_data_s *priv = NULL;
struct edma_msg_hdr_s *hdr = NULL;
unsigned long flags = 0;
int total_len = 0;
int ret = 0;
struct edma_host_s *phost = &g_bma_dev->edma_host;
if (!handle || !msg || msg_len == 0) {
BMA_LOG(DLOG_DEBUG, "input NULL point!\n");
......@@ -479,54 +477,80 @@ int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
return -EINVAL;
}
priv = (struct bma_priv_data_s *)handle;
priv = handle;
if (priv->user.type >= TYPE_MAX) {
BMA_LOG(DLOG_DEBUG, "error type = %d\n", priv->user.type);
return -EFAULT;
}
total_len = SIZE_OF_MSG_HDR + msg_len;
return 0;
}
static void edma_msg_hdr_init(struct edma_msg_hdr_s *hdr,
struct bma_priv_data_s *private_data,
char *msg_buf, size_t msg_len)
{
hdr->type = private_data->user.type;
hdr->sub_type = private_data->user.sub_type;
hdr->user_id = private_data->user.user_id;
hdr->datalen = msg_len;
BMA_LOG(DLOG_DEBUG, "msg_len is %zu\n", msg_len);
memcpy(hdr->data, msg_buf, msg_len);
}
int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
{
struct bma_priv_data_s *priv = NULL;
struct edma_msg_hdr_s *hdr = NULL;
unsigned long flags = 0;
unsigned int total_len = 0;
int ret = 0;
struct edma_host_s *phost = &g_bma_dev->edma_host;
char *msg_buf = NULL;
ret = check_cdev_add_msg_param(handle, msg, msg_len);
if (ret != 0)
return ret;
priv = (struct bma_priv_data_s *)handle;
total_len = (unsigned int)(SIZE_OF_MSG_HDR + msg_len);
if (phost->msg_send_write + total_len > HOST_MAX_SEND_MBX_LEN - SIZE_OF_MBX_HDR) {
BMA_LOG(DLOG_DEBUG, "msg lost,msg_send_write: %u,msg_len:%u,max_len: %d\n",
phost->msg_send_write, total_len, HOST_MAX_SEND_MBX_LEN);
return -ENOSPC;
}
msg_buf = (char *)kmalloc(msg_len, GFP_KERNEL);
if (!msg_buf) {
BMA_LOG(DLOG_ERROR, "malloc msg_buf failed\n");
return -ENOMEM;
}
if (copy_from_user(msg_buf, msg, msg_len)) {
BMA_LOG(DLOG_ERROR, "copy_from_user error\n");
kfree(msg_buf);
return -EFAULT;
}
spin_lock_irqsave(&phost->send_msg_lock, flags);
if (phost->msg_send_write + total_len <=
HOST_MAX_SEND_MBX_LEN - SIZE_OF_MBX_HDR) {
hdr = (struct edma_msg_hdr_s *)(phost->msg_send_buf +
phost->msg_send_write);
hdr->type = priv->user.type;
hdr->sub_type = priv->user.sub_type;
hdr->user_id = priv->user.user_id;
hdr->datalen = msg_len;
BMA_LOG(DLOG_DEBUG, "msg_len is %zu\n", msg_len);
if (copy_from_user(hdr->data, msg, msg_len)) {
BMA_LOG(DLOG_ERROR, "copy_from_user error\n");
ret = -EFAULT;
goto end;
}
hdr = (struct edma_msg_hdr_s *)(phost->msg_send_buf + phost->msg_send_write);
edma_msg_hdr_init(hdr, priv, msg_buf, msg_len);
phost->msg_send_write += total_len;
phost->statistics.send_bytes += total_len;
phost->statistics.send_pkgs++;
phost->msg_send_write += total_len;
phost->statistics.send_bytes += total_len;
phost->statistics.send_pkgs++;
#ifdef EDMA_TIMER
(void)mod_timer(&phost->timer, jiffies_64);
(void)mod_timer(&phost->timer, jiffies_64);
#endif
BMA_LOG(DLOG_DEBUG, "msg_send_write = %d\n",
phost->msg_send_write);
ret = msg_len;
goto end;
} else {
BMA_LOG(DLOG_DEBUG,
"msg lost,msg_send_write: %d,msg_len:%d,max_len: %d\n",
phost->msg_send_write, total_len,
HOST_MAX_SEND_MBX_LEN);
ret = -ENOSPC;
goto end;
}
BMA_LOG(DLOG_DEBUG, "msg_send_write = %d\n", phost->msg_send_write);
end:
ret = msg_len;
spin_unlock_irqrestore(&g_bma_dev->edma_host.send_msg_lock, flags);
kfree(msg_buf);
return ret;
}
EXPORT_SYMBOL_GPL(bma_cdev_add_msg);
......
......@@ -71,7 +71,7 @@ struct bma_pci_dev_s {
#ifdef DRV_VERSION
#define BMA_VERSION MICRO_TO_STR(DRV_VERSION)
#else
#define BMA_VERSION "0.3.4"
#define BMA_VERSION "0.3.5"
#endif
#ifdef CONFIG_ARM64
......
......@@ -23,7 +23,7 @@
#ifdef DRV_VERSION
#define KBOX_VERSION MICRO_TO_STR(DRV_VERSION)
#else
#define KBOX_VERSION "0.3.4"
#define KBOX_VERSION "0.3.5"
#endif
#define UNUSED(x) (x = x)
......
......@@ -135,7 +135,7 @@ int kbox_panic_init(void)
int ret = KBOX_TRUE;
g_panic_info_buf = kmalloc(SLOT_LENGTH, GFP_KERNEL);
if (IS_ERR(g_panic_info_buf) || !g_panic_info_buf) {
if (!g_panic_info_buf) {
KBOX_MSG("kmalloc g_panic_info_buf fail!\n");
ret = -ENOMEM;
goto fail;
......@@ -144,7 +144,7 @@ int kbox_panic_init(void)
memset(g_panic_info_buf, 0, SLOT_LENGTH);
g_panic_info_buf_tmp = kmalloc(SLOT_LENGTH, GFP_KERNEL);
if (IS_ERR(g_panic_info_buf_tmp) || !g_panic_info_buf_tmp) {
if (!g_panic_info_buf_tmp) {
KBOX_MSG("kmalloc g_panic_info_buf_tmp fail!\n");
ret = -ENOMEM;
goto fail;
......
......@@ -304,7 +304,7 @@ int kbox_printk_init(int kbox_proc_exist)
g_printk_info_buf = kmalloc(SECTION_PRINTK_LEN,
GFP_KERNEL);
if (IS_ERR(g_printk_info_buf) || !g_printk_info_buf) {
if (!g_printk_info_buf) {
KBOX_MSG("kmalloc g_printk_info_buf fail!\n");
ret = -ENOMEM;
goto fail;
......@@ -314,7 +314,7 @@ int kbox_printk_init(int kbox_proc_exist)
g_printk_info_buf_tmp = kmalloc(SECTION_PRINTK_LEN,
GFP_KERNEL);
if (IS_ERR(g_printk_info_buf_tmp) || !g_printk_info_buf_tmp) {
if (!g_printk_info_buf_tmp) {
KBOX_MSG("kmalloc g_printk_info_buf_tmp fail!\n");
ret = -ENOMEM;
goto fail;
......
......@@ -432,7 +432,7 @@ int kbox_write_op(long long offset, unsigned int count,
return KBOX_FALSE;
temp_buf_char = kmalloc(TEMP_BUF_DATA_SIZE, GFP_KERNEL);
if (!temp_buf_char || IS_ERR(temp_buf_char)) {
if (!temp_buf_char) {
KBOX_MSG("kmalloc temp_buf_char fail!\n");
up(&user_sem);
return -ENOMEM;
......
......@@ -638,6 +638,7 @@ s32 veth_refill_rxskb(struct bspveth_rxtx_q *prx_queue, int queue)
next_to_fill = (next_to_fill + 1) & BSPVETH_POINT_MASK;
}
mb();/* memory barriers. */
prx_queue->next_to_fill = next_to_fill;
tail = prx_queue->tail;
......@@ -672,6 +673,7 @@ s32 bspveth_setup_rx_skb(struct bspveth_device *pvethdev,
if (!idx) /* Can't alloc even one packets */
return -EFAULT;
mb();/* memory barriers. */
prx_queue->next_to_fill = idx;
VETH_LOG(DLOG_DEBUG, "prx_queue->next_to_fill=%d\n",
......@@ -886,8 +888,6 @@ s32 bspveth_setup_all_rx_resources(struct bspveth_device *pvethdev)
err = bspveth_setup_rx_resources(pvethdev,
pvethdev->prx_queue[qid]);
if (err) {
kfree(pvethdev->prx_queue[qid]);
pvethdev->prx_queue[qid] = NULL;
VETH_LOG(DLOG_ERROR,
"Allocation for Rx Queue %u failed\n", qid);
......@@ -1328,6 +1328,7 @@ s32 veth_send_one_pkt(struct sk_buff *skb, int queue)
pbd_v->off = off;
pbd_v->len = skb->len;
mb();/* memory barriers. */
head = (head + 1) & BSPVETH_POINT_MASK;
ptx_queue->head = head;
......@@ -1424,6 +1425,7 @@ s32 veth_free_txskb(struct bspveth_rxtx_q *ptx_queue, int queue)
next_to_free = (next_to_free + 1) & BSPVETH_POINT_MASK;
}
mb(); /* memory barriers. */
ptx_queue->next_to_free = next_to_free;
tail = ptx_queue->tail;
......@@ -1522,6 +1524,7 @@ s32 veth_recv_pkt(struct bspveth_rxtx_q *prx_queue, int queue)
}
}
mb();/* memory barriers. */
prx_queue->tail = tail;
head = prx_queue->head;
......
......@@ -31,7 +31,7 @@ extern "C" {
#ifdef DRV_VERSION
#define VETH_VERSION MICRO_TO_STR(DRV_VERSION)
#else
#define VETH_VERSION "0.3.4"
#define VETH_VERSION "0.3.5"
#endif
#define MODULE_NAME "veth"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册