Blog:
Fixing a 10-year-old vulnerability in early-stage boot on NXP processors

Freitag, 6. November 2026

On Wednesday morning, a security researcher named Ana Bobillo posted a message and patch series to the u-boot mailing list with the somewhat innocuous subject line “usb: gadget: f_sdp: honour a closed i.MX part, bound ep0 data”.

So far, the importance of this patch series seems not to have been noticed by the broader internet. This is a vulnerability that allows someone with physical access to a secure-boot protected board to boot their own, unsigned software, if the board can be put into a recovery mode where firmware reflashing is allowed. We’ve already posted a security notice with the relevant details, and I’ve ported the patch series to meta-toradex-security so that affected Toradex customers have a path to patching if it affects them.

In this blog post, I want to walk through exactly why and how this vulnerability is serious, and give a behind-the-scenes look at how the Torizon product security team deals with issues like this.

What is secure boot?

Secure boot, in general, is the process of booting an image that comes from a valid trusted source (authenticity check) while ensuring it has not been modified in any way (integrity check). It always needs to start with a trusted root; in the case of NXP processors this is called High Assurance Boot (HAB) or Advanced High Assurance Boot (AHAB). You can fuse some public keys into protected, one-time-programmable fuses on the SoC, and from then on the processor will only be willing to boot code that has been signed by one of those keys.

In practice, this is only the very first stage of the secure boot process. There’s some immutable boot ROM code that checks the signature on the very first boot container that loads, but to have a complete secure boot process you need to have a chain, where every stage of boot verifies the subsequent stage before loading:

Secure Boot Process
How is secure boot bypassed here?

This particular vulnerability is in u-boot, a widely-used bootloader. In particular, the vulnerability is in u-boot SPL, which is a very small bootloader that loads as a first boot phase, and then hands off to the larger u-boot proper.

The exploit here leverages something called the serial download protocol (SDP). Normally, you only want a device to boot the software that is flashed onto it, i.e. on the eMMC chip on the module. But sometimes, to recover a bricked device, you might want to be able to reflash the contents of the eMMC, even if you can’t boot the device. That’s where SDP comes in. It’s a protocol developed by NXP that allows you to send a new image to the device when it’s bricked. When the processor is in recovery mode, the SDP listener will activate, and the processor will accept a new bootloader over this protocol.

Naturally, when secure boot is active, the boot ROM checks whether the bootloader is signed before loading it. That part is working fine. However, there’s a bit of a problem if you want to use SDP to flash a whole boot environment on a board that uses u-boot SPL: the boot ROM hands off execution to the SPL, and the SPL is the thing that has to load the full bootloader. So, u-boot SPL also implements this serial download protocol, to allow you to also send over the next bootloader stage. This is where the vulnerability comes in.

The SDP implementation in u-boot SPL accepts an instruction about where to load the second-stage bootloader from via an unauthenticated path. More bluntly: once the signed SPL is running, it pretends to be the same recovery interface the boot ROM offered, but without checking signatures the way the ROM does. That means that an attacker with physical USB access can in principle boot a valid, signed SPL from a legitimate firmware image, wait for the handoff to the SDP implementation in the SPL, and then tell the SPL to write and jump to unsigned code. From the SoC’s point of view the chain of trust already looked fine—the ROM checked the first stage—so everything after that runs as if it were trusted. Secure boot on the NXP processor implementation itself never failed, but the first stage after the boot ROM passed control over to the bootloader is what fails to continue the verification and breaks the chain.

Studying the issue and analyzing the scope

As soon as we read the patch series we realized this was serious. But we didn’t yet know the degree to which Toradex modules might be affected. We provide secure boot via meta-toradex-security, and it includes some significant hardening patches in u-boot to make it more resilient. Additionally, not every module even uses u-boot SPL in its bootflow: some modules can boot u-boot proper directly from boot ROM. So our first step was carefully analyzing the vulnerable code path and our board defconfigs first, to confirm which modules make use of SPL, and whether the SPL build for those modules actually builds the vulnerable code by default.

There were three key findings (all identified by Ana Bobillo, the researcher who found and posted the fix). For this section, I’m linking to the source code for the latest stable release of u-boot on gitlab, but in our actual investigation we verified everything on the exact revisions that are build by default for each board, to make sure we took into account any variation based on board type, or any patches from NXP’s u-boot distribution that might mitigate the issue.

I won’t recap those findings in detail as they’re described in the security notice, but that investigation showed us that 6 modules would potentially be affected: Apalis iMX6, Colibri iMX6, Verdin iMX8M Mini, Verdin iMX95, Aquila iMX95, and SMARC iMX95. The remaining modules either don’t build SDP at all, or only have SDP reachable through u-boot proper, where our hardening patches already prevent exploitation.

For the six that are potentially vulnerable, we still wanted to verify on real hardware that the vulnerability is exploitable under practical conditions.

Proving the exploit, and the fix

We took one of the boards that our analysis said should be affected, fused it with some new keys, and started setting up our test environment.

The issue here should be fairly easy to replicate, in principle: get the device into recovery mode, start an SDP session, and tell the board to jump to an unauthenticated address. To do that, we used the imx_usb tool with a modified config, so that it would tell SPL to jump to an address we sent over the wire, rather than the address specified in the signed image header.

We also wanted a nice, programmatic way to put it into recovery mode. My colleague Stefano Viola pointed out that the processor will automatically go into recovery mode if there’s no valid bootloader for it to run, so rather than pushing the button we just zeroed out the first few bytes of the bootloader partition and rebooted.

Once we did that, we could see the device come up in SDP mode. We used imx_usb to send over the signed-but-vulnerable boot package, watched it boot into u-boot SPL, and attempted to get it to jump to an unvalidated, externally supplied address. So that we could easily see a result on the console without too much extra effort, the address we supplied was actually the address of u-boot SDP itself. The correct behaviour would be
We observed the following on the board’s serial console:

Downloading file of size 56136 to 0x10000000... done
Jumping to header at 0x10000000
Jumping to 0x00908000      # this is already the attacker-controlled code

And on the host running imx_usb:

HAB security state: development mode (0x56787856)
...
loading binary file(SPL) to 10000000, skip=0, fsize=db48 type=aa
<<<56136, 56136 bytes>>>
    # 0x56787856 is SDP_SECURITY_OPEN, but the board is actually closed
succeeded (security 0x56787856, status 0x88888888) 
jumping to 0x10000000              # attacker-controlled value, unvalidated
imx_usb rc=0

We then attempted the same jump, but with a patched bootloader (from Ana Bobillo’s patch series, applied via meta-toradex-security). Note that we had it jump to 0x10000000 because it’s a valid header, so it made it easier On the board’s serial console:

Industrial temperature grade DDR3 timings, 64bit bus width.
Trying to boot from USB SDP
SDP: initialize...
SDP: handle requests...
Downloading file of size 56136 to 0x10000000... done
Jumping to header at 0x10000000
Found header at 0x10000000  # logs stop here, no further execution

…and on the host:

HAB security state: production mode (0x12343412)
...
loading binary file(SPL) to 10000000, skip=0, fsize=db48 type=aa
<<<56136, 56136 bytes>>>
    # 0x12343412 is SDP_SECURITY_CLOSED, reported correctly
succeeded (security 0x12343412, status 0x88888888)
jumping to 0x10000000
failed (security 0x12343412, status 0x33333333) # imx_usb correctly reports the refusal, and the reason

The fix is validated! We can no longer tell u-boot where to jump to without authentication, and the lifecycle status is correctly reported back to the tool.

Side note: Where did the vulnerability come from?

This vulnerability had been lurking in the u-boot codebase since 2017, when the SDP driver was originally added. SDP is used in recovery mode flows all the time, and as such NXP has included it in their u-boot distributions as far back as I could see. One interesting point: when I checked the original author of that SDP driver, it was actually a former Toradex employee. We’ve been a prolific contributor to embedded Linux over the years, so it’s not a surprise that we’ve also written our fair share of bugs. I want to publicly say thank you to Ana for finding this one, and patching it. This is open source working as it should.

Next steps

The patch series is currently under review in u-boot. We have also publicly posted a merge request to meta-toradex-security that applies Ana Bobillo’s patch series (lightly adapted to specific u-boot versions), and that code is what we used in the fix verification described here.

We intend to wait until upstream reviews and merges the patch series to merge the patches into meta-toradex-security, to avoid churn if there are changes requested.

Kontaktieren Sie unsere Experten

?Haben Sie eine Frage