Commit de877437 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

mei: check for error returned from mei_hbuf_empty_slots()

mei_hbuf_empty_slots() may return with an error in case
of circular buffer overflow. This type of error may
be caused only by a bug. However currently, the error
won't be detected due signed type promotion in comparison to u32.
We add explicit check for less then zero and explicit cast
in comparison to suppress singn-compare warning.
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a103af1b
...@@ -865,8 +865,10 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -865,8 +865,10 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
if (slots < msg_slots) if ((u32)slots < msg_slots)
return -EMSGSIZE; return -EMSGSIZE;
ret = mei_cl_send_disconnect(cl, cb); ret = mei_cl_send_disconnect(cl, cb);
...@@ -1054,12 +1056,15 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1054,12 +1056,15 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
int rets; int rets;
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
slots = mei_hbuf_empty_slots(dev);
if (mei_cl_is_other_connecting(cl)) if (mei_cl_is_other_connecting(cl))
return 0; return 0;
if (slots < msg_slots) slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
if ((u32)slots < msg_slots)
return -EMSGSIZE; return -EMSGSIZE;
rets = mei_cl_send_connect(cl, cb); rets = mei_cl_send_connect(cl, cb);
...@@ -1296,8 +1301,10 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1296,8 +1301,10 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
if (slots < msg_slots) if ((u32)slots < msg_slots)
return -EMSGSIZE; return -EMSGSIZE;
request = mei_cl_notify_fop2req(cb->fop_type); request = mei_cl_notify_fop2req(cb->fop_type);
...@@ -1573,6 +1580,9 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1573,6 +1580,9 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
} }
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
len = buf->size - cb->buf_idx; len = buf->size - cb->buf_idx;
msg_slots = mei_data2slots(len); msg_slots = mei_data2slots(len);
...@@ -1581,11 +1591,11 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1581,11 +1591,11 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
mei_hdr.reserved = 0; mei_hdr.reserved = 0;
mei_hdr.internal = cb->internal; mei_hdr.internal = cb->internal;
if (slots >= msg_slots) { if ((u32)slots >= msg_slots) {
mei_hdr.length = len; mei_hdr.length = len;
mei_hdr.msg_complete = 1; mei_hdr.msg_complete = 1;
/* Split the message only if we can write the whole host buffer */ /* Split the message only if we can write the whole host buffer */
} else if (slots == dev->hbuf_depth) { } else if ((u32)slots == dev->hbuf_depth) {
msg_slots = slots; msg_slots = slots;
len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); len = (slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
mei_hdr.length = len; mei_hdr.length = len;
......
...@@ -540,8 +540,11 @@ static int mei_me_hbuf_write(struct mei_device *dev, ...@@ -540,8 +540,11 @@ static int mei_me_hbuf_write(struct mei_device *dev,
empty_slots = mei_hbuf_empty_slots(dev); empty_slots = mei_hbuf_empty_slots(dev);
dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots); dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots);
if (empty_slots < 0)
return -EOVERFLOW;
dw_cnt = mei_data2slots(length); dw_cnt = mei_data2slots(length);
if (empty_slots < 0 || dw_cnt > empty_slots) if (dw_cnt > (u32)empty_slots)
return -EMSGSIZE; return -EMSGSIZE;
mei_me_hcbww_write(dev, *((u32 *) header)); mei_me_hcbww_write(dev, *((u32 *) header));
......
...@@ -709,7 +709,7 @@ static int mei_txe_write(struct mei_device *dev, ...@@ -709,7 +709,7 @@ static int mei_txe_write(struct mei_device *dev,
struct mei_txe_hw *hw = to_txe_hw(dev); struct mei_txe_hw *hw = to_txe_hw(dev);
unsigned long rem; unsigned long rem;
unsigned long length; unsigned long length;
int slots = dev->hbuf_depth; u32 slots = dev->hbuf_depth;
u32 *reg_buf = (u32 *)buf; u32 *reg_buf = (u32 *)buf;
u32 dw_cnt; u32 dw_cnt;
int i; int i;
......
...@@ -173,10 +173,12 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -173,10 +173,12 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
int slots; int slots;
int ret; int ret;
slots = mei_hbuf_empty_slots(dev);
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_response)); msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_response));
slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
if (slots < msg_slots) if ((u32)slots < msg_slots)
return -EMSGSIZE; return -EMSGSIZE;
ret = mei_hbm_cl_disconnect_rsp(dev, cl); ret = mei_hbm_cl_disconnect_rsp(dev, cl);
...@@ -208,8 +210,10 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -208,8 +210,10 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0)
return -EOVERFLOW;
if (slots < msg_slots) if ((u32)slots < msg_slots)
return -EMSGSIZE; return -EMSGSIZE;
ret = mei_hbm_cl_flow_control_req(dev, cl); ret = mei_hbm_cl_flow_control_req(dev, cl);
...@@ -365,7 +369,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list) ...@@ -365,7 +369,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list)
return 0; return 0;
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots <= 0) if (slots < 0)
return -EOVERFLOW;
if (slots == 0)
return -EMSGSIZE; return -EMSGSIZE;
/* complete all waiting for write CB */ /* complete all waiting for write CB */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment