driverdev-devel.linuxdriverproject.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Jules Irenge <jbi.octave@gmail.com>
Cc: devel@driverdev.osuosl.org, gregkh@linuxfoundation.org,
	Boqun.Feng@microsoft.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] staging: wfx: add gcc extension __force cast
Date: Mon, 11 Nov 2019 23:16:59 +0000	[thread overview]
Message-ID: <20191111231659.GA22837@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20191111202852.GX26530@ZenIV.linux.org.uk>

On Mon, Nov 11, 2019 at 08:28:52PM +0000, Al Viro wrote:

> So it smells like a remote buffer overrun, little-endian or not.
> And at that point I would start looking for driver original authors with
> some rather pointed questions about the validation of data and lack
> thereof.
> 
> BTW, if incoming packets are fixed-endian, I would expect more bugs on
> big-endian hosts - wfx_tx_confirm_cb() does things like
>                 tx_info->status.tx_time =
>                 arg->media_delay - arg->tx_queue_delay;
> with media_delay and tx_queue_delay both being 32bit fields in the
> incoming packet.  So another question to the authors (or documentation,
> or direct experiments) is what endianness do various fields in the incoming
> data have.  We can try and guess, but...

More fun:
int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, size_t val_len)
{
        int ret;
        struct hif_msg *hif;
        int buf_len = sizeof(struct hif_cnf_read_mib) + val_len;
        struct hif_req_read_mib *body = wfx_alloc_hif(sizeof(*body), &hif);
        struct hif_cnf_read_mib *reply = kmalloc(buf_len, GFP_KERNEL);

OK, allocated request and reply buffers, by the look of it; request one
being struct hif_msg with struct hif_req_read_mib for payload
and reply - struct hif_cnf_read_mib {
        uint32_t   status;
        uint16_t   mib_id;
        uint16_t   length;
        uint8_t    mib_data[];
} with val_len bytes in mib_data.

        body->mib_id = cpu_to_le16(mib_id);
        wfx_fill_header(hif, vif_id, HIF_REQ_ID_READ_MIB, sizeof(*body));

Filled request, {.len = cpu_to_le16(4 + 4),
		 .id = HIF_REQ_ID_READ_MIB,
		 .interface = vif_id,
		 .body = {
			.mib_id = cpu_to_le16(mib_id)
		}
	}
Note that mib_id is host-endian here; what we send is little-endian.

        ret = wfx_cmd_send(wdev, hif, reply, buf_len, false);
send it, get reply

        if (!ret && mib_id != reply->mib_id) {
Wha...?  Now we are comparing two bytes at offset 4 into reply with a host-endian
value?  Oh, well...

                dev_warn(wdev->dev, "%s: confirmation mismatch request\n", __func__);
                ret = -EIO;
        }
        if (ret == -ENOMEM)
                dev_err(wdev->dev, "buffer is too small to receive %s (%zu < %d)\n",
                        get_mib_name(mib_id), val_len, reply->length);
        if (!ret)
                memcpy(val, &reply->mib_data, reply->length);
What.  The.  Hell?

We are copying data from the reply.  Into caller-supplied object.
With length taken from the same reply and no validation even
attempted?  Not even "um, maybe we shouldn't copy more than the caller
told us to copy, especially since that's as much as there is in the
source of that memcpy"?

And that's besides the endianness questions.  Note that getting the
endianness wrong here is just about certain to blow up - small value
will be misinterpreted by factor of 256.

In any case, even if this is talking to firmware on a card, that's
an unhealthy degree of trust, especially since the same function
does consider the possibility of bogus replies.
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

  reply	other threads:[~2019-11-11 23:17 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-08 23:38 [PATCH] staging: wfx: add gcc extension __force cast Jules Irenge
2019-11-09  8:36 ` Greg KH
2019-11-09  9:19 ` Al Viro
2019-11-11 13:51   ` Jules Irenge
2019-11-11 20:28     ` Al Viro
2019-11-11 23:16       ` Al Viro [this message]
2019-11-12 12:00         ` Jerome Pouiller
2019-11-12 11:32       ` Jerome Pouiller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191111231659.GA22837@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=Boqun.Feng@microsoft.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jbi.octave@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).