public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
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 --]

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox