From: Tom Rini <trini@konsulko.com>
To: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Cc: u-boot@lists.denx.de, Fabio Estevam <festevam@denx.de>,
Nicolas Bidron <nicolas.bidron@nccgroup.com>,
Joe Hershberger <joe.hershberger@ni.com>,
Ramon Fried <rfried.dev@gmail.com>
Subject: Re: [PATCH 3/6] net: (actually/better) deal with CVE-2022-{30790,30552}
Date: Mon, 28 Nov 2022 14:51:22 -0500 [thread overview]
Message-ID: <20221128195122.GD3787616@bill-the-cat> (raw)
In-Reply-To: <20221014174342.3216982-4-rasmus.villemoes@prevas.dk>
[-- Attachment #1: Type: text/plain, Size: 4585 bytes --]
On Fri, Oct 14, 2022 at 07:43:39PM +0200, Rasmus Villemoes wrote:
> I hit a strange problem with v2022.10: Sometimes my tftp transfer
> would seemingly just hang. It only happened for some files. Moreover,
> changing tftpblocksize from 65464 to 65460 or 65000 made it work again
> for all the files I tried. So I started suspecting it had something to
> do with the file sizes and in particular the way the tftp blocks get
> fragmented and reassembled.
>
> v2022.01 showed no problems with any of the files or any value of
> tftpblocksize.
>
> Looking at what had changed in net.c or tftp.c since January showed
> only one remotely interesting thing, b85d130ea0ca.
>
> So I fired up wireshark on my host to see if somehow one of the
> packets would be too small. But no, with both v2022.01 and v2022.10,
> the exact same sequence of packets were sent, all but the last of size
> 1500, and the last being 1280 bytes.
>
> But then it struck me that 1280 is 5*256, so one of the two bytes
> on-the-wire is 0 and the other is 5, and when then looking at the code
> again the lack of endianness conversion becomes obvious. [ntohs is
> both applied to ip->ip_off just above, as well as to ip->ip_len just a
> little further down when the "len" is actually computed].
>
> IOWs the current code would falsely reject any packet which happens to
> be a multiple of 256 bytes in size, breaking tftp transfers somewhat
> randomly, and if it did get one of those "malicious" packets with
> ip_len set to, say, 27, it would be seen by this check as being 6912
> and hence not rejected.
>
> ====
>
> Now, just adding the missing ntohs() would make my initial problem go
> away, in that I can now download the file where the last fragment ends
> up being 1280 bytes. But there's another bug in the code and/or
> analysis: The right-hand side is too strict, in that it is ok for the
> last fragment not to have a multiple of 8 bytes as payload - it really
> must be ok, because nothing in the IP spec says that IP datagrams must
> have a multiple of 8 bytes as payload. And comments in the code also
> mention this.
>
> To fix that, replace the comparison with <= IP_HDR_SIZE and add
> another check that len is actually a multiple of 8 when the "more
> fragments" bit is set - which it necessarily is for the case where
> offset8 ends up being 0, since we're only called when
>
> (ip_off & (IP_OFFS | IP_FLAGS_MFRAG)).
>
> ====
>
> So, does this fix CVE-2022-30790 for real? It certainly correctly
> rejects the POC code which relies on sending a packet of size 27 with
> the MFRAG flag set. Can the attack be carried out with a size 27
> packet that doesn't set MFRAG (hence must set a non-zero fragment
> offset)? I dunno. If we get a packet without MFRAG, we update
> h->last_byte in the hole we've found to be start+len, hence we'd enter
> one of
>
> if ((h >= thisfrag) && (h->last_byte <= start + len)) {
>
> or
>
> } else if (h->last_byte <= start + len) {
>
> and thus won't reach any of the
>
> /* overlaps with initial part of the hole: move this hole */
> newh = thisfrag + (len / 8);
>
> /* fragment sits in the middle: split the hole */
> newh = thisfrag + (len / 8);
>
> IOW these division are now guaranteed to be exact, and thus I think
> the scenario in CVE-2022-30790 cannot happen anymore.
>
> ====
>
> However, there's a big elephant in the room, which has always been
> spelled out in the comments, and which makes me believe that one can
> still cause mayhem even with packets whose payloads are all 8-byte
> aligned:
>
> This code doesn't deal with a fragment that overlaps with two
> different holes (thus being a superset of a previously-received
> fragment).
>
> Suppose each character below represents 8 bytes, with D being already
> received data, H being a hole descriptor (struct hole), h being
> non-populated chunks, and P representing where the payload of a just
> received packet should go:
>
> DDDHhhhhDDDDHhhhDDDD
> PPPPPPPPP
>
> I'm pretty sure in this case we'd end up with h being the first hole,
> enter the simple
>
> } else if (h->last_byte <= start + len) {
> /* overlaps with final part of the hole: shorten this hole */
> h->last_byte = start;
>
> case, and thus in the memcpy happily overwrite the second H with our
> chosen payload. This is probably worth fixing...
>
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Applied to u-boot/master, thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
next prev parent reply other threads:[~2022-11-28 19:51 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-14 17:43 [PATCH 0/6] broken CVE fix (b85d130ea0ca) Rasmus Villemoes
2022-10-14 17:43 ` [PATCH 1/6] net: improve check for no IP options Rasmus Villemoes
2022-10-16 18:23 ` Ramon Fried
2022-11-28 19:51 ` Tom Rini
2022-10-14 17:43 ` [PATCH 2/6] net: compare received length to sizeof(ip_hdr), not sizeof(ip_udp_hdr) Rasmus Villemoes
2022-11-28 19:51 ` Tom Rini
2022-10-14 17:43 ` [PATCH 3/6] net: (actually/better) deal with CVE-2022-{30790,30552} Rasmus Villemoes
2022-11-28 19:51 ` Tom Rini [this message]
2022-10-14 17:43 ` [PATCH 4/6] net: fix ip_len in reassembled IP datagram Rasmus Villemoes
2022-11-28 19:51 ` Tom Rini
2022-10-14 17:43 ` [PATCH 5/6] net: tftp: use IS_ENABLED(CONFIG_NET_TFTP_VARS) instead of #if Rasmus Villemoes
2022-10-16 18:28 ` Ramon Fried
2022-10-17 6:18 ` Rasmus Villemoes
2022-11-28 19:51 ` Tom Rini
2022-10-14 17:43 ` [PATCH 6/6] net: tftp: sanitize tftp block size, especially for TX Rasmus Villemoes
2022-10-16 18:30 ` Ramon Fried
2022-11-28 19:51 ` Tom Rini
2022-10-15 12:57 ` [PATCH 0/6] broken CVE fix (b85d130ea0ca) Fabio Estevam
2022-10-17 7:52 ` [PATCH 7/6] net: deal with fragment-overlapping-two-holes case Rasmus Villemoes
2022-11-28 19:52 ` Tom Rini
2022-11-14 9:35 ` [PATCH 0/6] broken CVE fix (b85d130ea0ca) Rasmus Villemoes
2022-11-14 13:04 ` Tom Rini
2022-11-17 0:32 ` Fabio Estevam
2022-11-28 8:10 ` Rasmus Villemoes
-- strict thread matches above, loose matches on Subject: below --
2022-10-18 16:41 [PATCH 3/6] net: (actually/better) deal with CVE-2022-{30790, 30552} Artur Łącki
2022-10-20 15:32 Artur Łącki
2022-10-25 23:30 ` Rasmus Villemoes
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=20221128195122.GD3787616@bill-the-cat \
--to=trini@konsulko.com \
--cc=festevam@denx.de \
--cc=joe.hershberger@ni.com \
--cc=nicolas.bidron@nccgroup.com \
--cc=rasmus.villemoes@prevas.dk \
--cc=rfried.dev@gmail.com \
--cc=u-boot@lists.denx.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.