netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Bagas Sanjaya <bagasdotme@gmail.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linux Wireless <linux-wireless@vger.kernel.org>,
	Linux Networking <netdev@vger.kernel.org>,
	M Chetan Kumar <m.chetan.kumar@linux.intel.com>,
	"David S. Miller" <davem@davemloft.net>,
	Florian Klink <flokli@flokli.de>,
	linux-hardening@vger.kernel.org
Subject: Re: Fwd: iosm: detected field-spanning write for XMM7360
Date: Tue, 20 Jun 2023 12:32:36 -0700	[thread overview]
Message-ID: <202306201148.716CFF3@keescook> (raw)
In-Reply-To: <0826b484-8bbc-d58f-2caf-7015bd30f827@leemhuis.info>

[regressions list to Bcc]

On Tue, Jun 20, 2023 at 11:12:40AM +0200, Linux regression tracking (Thorsten Leemhuis) wrote:
> On 20.06.23 10:44, Bagas Sanjaya wrote:
> > I notice a regression report on Bugzilla [1]. Quoting from it:
> [...]
> >> [Sa Jun 17 20:10:09 2023] memcpy: detected field-spanning write (size 16) of single field "&adth->dg" at drivers/net/wwan/iosm/iosm_ipc_mux_codec.c:852 (size 8)
> [...]
> > [1]: https://bugzilla.kernel.org/show_bug.cgi?id=217569

This looks like a legitimate bug.

Here are the structures used by drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
leading up to the memcpy() triggering this warning at line 852, with
commentary from me added:

struct mux_adb {
        struct sk_buff *dest_skb;
        u8 *buf;			// <- unbounded array
	...
};

/**
 * struct mux_adth - Structure of the Aggregated Datagram Table Header.
 ...
 * @dg:	datagramm table with variable length	// variable length you say? :)
 */
struct mux_adth {
	...
        struct mux_adth_dg dg;		// <- destination of memcpy
};

struct mux_adth_dg {
        __le32 datagram_index;
        __le16 datagram_length;
        u8 service_class;
        u8 reserved;
};					// 8 byte structure

static void ipc_mux_ul_encode_adth(struct iosm_mux *ipc_mux,
                                   struct mux_adb *ul_adb, int *out_offset)
{
	...
        struct mux_adth *adth;
	...
			// Assignment of fixed-sized structure on an
			// unbounded string (i.e. minimum size
			// constraint is now defined by structure
			// layout, which is a good thing.)
                        adth = (struct mux_adth *)&ul_adb->buf[offset];
			...
			// This appears to be preparing for having
			// _multiple_ "dg" structs at the end of
			// struct mux_adth_dg, not just 1. (And, if so,
			// should be using the struct_size(), or really,
			// given the later subtraction, the flex_size(),
			// helper.)
                        adth_dg_size = offsetof(struct mux_adth, dg) +
                                        ul_adb->dg_count[i] * sizeof(*dg);
			...
                        adth_dg_size -= offsetof(struct mux_adth, dg);
                        memcpy(&adth->dg, ul_adb->dg[i], adth_dg_size);


&adth->dg is 8 bytes, so the warning message is correct. However, it
seems like "ul_adb->dg_count[i]" contains a _count_ of "dg" structures
to copy, and, in the reported case, is "2".

The fix appears to be adjusting struct mux_adth with:

-       struct mux_adth_dg dg;
+       struct mux_adth_dg dg[];

But, since this is an implicit "1-element array to flexible array"
conversion[1], we need to double-check "sizeof" uses.

I only see 3 cases of sizeof(struct mux_adth). This one removes the
"extra" "dg" element for bounds checking:

                if (le16_to_cpu(adth->table_length) < (sizeof(struct mux_adth) -
                                sizeof(struct mux_adth_dg)))

This one adds it back in after subtracting 1 too many:

                nr_of_dg = (le16_to_cpu(adth->table_length) -
                                        sizeof(struct mux_adth) +
                                        sizeof(struct mux_adth_dg)) /
                                        sizeof(struct mux_adth_dg);

As does this one:

                        nr_of_dg = (le16_to_cpu(adth->table_length) -
                                        sizeof(struct mux_adth) +
                                        sizeof(struct mux_adth_dg)) /
                                        sizeof(struct mux_adth_dg);

So they can be simplified to avoid the extra math.

I'll send a patch...

-Kees

[1] https://github.com/KSPP/linux/issues/79

-- 
Kees Cook

      parent reply	other threads:[~2023-06-20 19:32 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-20  8:44 Fwd: iosm: detected field-spanning write for XMM7360 Bagas Sanjaya
2023-06-20  9:12 ` Linux regression tracking (Thorsten Leemhuis)
2023-06-20 12:25   ` Bagas Sanjaya
2023-06-20 19:32   ` Kees Cook [this message]

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=202306201148.716CFF3@keescook \
    --to=keescook@chromium.org \
    --cc=bagasdotme@gmail.com \
    --cc=davem@davemloft.net \
    --cc=flokli@flokli.de \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=m.chetan.kumar@linux.intel.com \
    --cc=netdev@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).