[LEDE-DEV] Fix for uqmi crash when using qmi-via-mbim (--mbim / -m)
Mogens Lauridsen
mlauridsen at gmail.com
Tue Nov 22 05:10:06 PST 2016
Seems like a better fix, but it doesn't work. uqmi hangs, so I suspect
that EM7455 has misunderstood the command. I have removed/replaced the
ustream_write(..,..,.., true) and after the changes below it works.
I guess it has something to do with the write being split in two.
I don't know what the maximum size of buffer should be, so I used:
2048+sizeof(struct mbim_command_message)
--- dev.c_ 2016-11-22 13:49:36.953419346 +0100
+++ dev.c 2016-11-22 14:03:27.089424031 +0100
@@ -161,9 +161,10 @@
int qmi_request_start(struct qmi_dev *qmi, struct qmi_request *req,
struct qmi_msg *msg, request_cb cb)
{
+ char buf[2048+sizeof(struct mbim_command_message)];
+ int buf_len = 0;
int len = qmi_complete_request_message(msg);
uint16_t tid;
- char *buf = (void *) msg;
memset(req, 0, sizeof(*req));
req->ret = -1;
@@ -188,13 +189,14 @@
list_add(&req->list, &qmi->req);
if (qmi->is_mbim) {
- struct mbim_command_message mbim;
- mbim_qmi_cmd(&mbim, len, tid);
- ustream_write(&qmi->sf.stream, (void *) &mbim, sizeof(mbim), true);
+ mbim_qmi_cmd((struct mbim_command_message *)buf, len, tid);
+ buf_len += sizeof(struct mbim_command_message);
}
+ memcpy(buf + buf_len, msg, len);
+ buf_len += len;
- dump_packet("Send packet", buf, len);
- ustream_write(&qmi->sf.stream, buf, len, false);
+ dump_packet("Send packet", buf, buf_len);
+ ustream_write(&qmi->sf.stream, buf, buf_len, false);
return 0;
}
On Tue, Nov 22, 2016 at 1:12 PM, Felix Fietkau <nbd at nbd.name> wrote:
> On 2016-11-22 12:47, Mogens Lauridsen wrote:
>> Hi,
>>
>> I found a memory overwrite causing a crash when using uqmi and
>> qmi-via-mbim such as:
>> uqmi -m -d /dev/cdc-wdm0 --get-signal-info
>>
>> The problem is missing space for mbim header, which is assumed in
>> qmi_request_start():
>>
>> if (qmi->is_mbim) {
>> buf -= sizeof(struct mbim_command_message);
>>
>> I have fixed it by added a new buffer "buf_" and set the original "buf"
>> to point inside "buf_"
> I have a better fix in mind. Please try this:
>
> diff --git a/dev.c b/dev.c
> index 9bf7ab2..9662a9a 100644
> --- a/dev.c
> +++ b/dev.c
> @@ -38,11 +38,8 @@ static const uint8_t qmi_services[__QMI_SERVICE_LAST] = {
> #undef __qmi_service
>
> static struct {
> - struct mbim_command_message mbim;
> - union {
> - char buf[512];
> - struct qmi_msg msg;
> - } u;
> + char buf[512];
> + struct qmi_msg msg;
> } __packed msgbuf;
>
> #ifdef DEBUG_PACKET
> @@ -191,9 +188,9 @@ int qmi_request_start(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_m
> list_add(&req->list, &qmi->req);
>
> if (qmi->is_mbim) {
> - buf -= sizeof(struct mbim_command_message);
> - mbim_qmi_cmd((struct mbim_command_message *) buf, len, tid);
> - len += sizeof(struct mbim_command_message);
> + struct mbim_command_message mbim;
> + mbim_qmi_cmd(&mbim, len, tid);
> + ustream_write(&qmi->sf.stream, (void *) &mbim, sizeof(mbim), true);
> }
>
> dump_packet("Send packet", buf, len);
> @@ -260,7 +257,7 @@ int qmi_service_connect(struct qmi_dev *qmi, QmiService svc, int client_id)
> };
> struct qmi_connect_request req;
> int idx = qmi_get_service_idx(svc);
> - struct qmi_msg *msg = &msgbuf.u.msg;
> + struct qmi_msg *msg = &msgbuf.msg;
>
> if (idx < 0)
> return -1;
> @@ -299,7 +296,7 @@ static void __qmi_service_disconnect(struct qmi_dev *qmi, int idx)
> )
> };
> struct qmi_request req;
> - struct qmi_msg *msg = &msgbuf.u.msg;
> + struct qmi_msg *msg = &msgbuf.msg;
>
> qmi->service_connected &= ~(1 << idx);
> qmi->service_data[idx].client_id = -1;
>
More information about the Lede-dev
mailing list