* [PATCH v1 0/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations @ 2026-04-28 5:52 Kane Chen 2026-04-28 5:52 ` [PATCH v1 1/1] " Kane Chen 0 siblings, 1 reply; 10+ messages in thread From: Kane Chen @ 2026-04-28 5:52 UTC (permalink / raw) To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here Cc: Troy Lee, Kane Chen This series fixes a bounds issue in Aspeed OTP programming through the Secure Boot Controller path. The guest-provided OTP address is word-indexed in the SBC model, but the OTP device write path operates on byte offsets. Passing the value through without validation/conversion could lead to out-of-range writes. The patch adds bounds checking in aspeed_sbc_otp_prog() before converting the address to a byte offset, and aligns the OTP write helper interfaces with byte-offset semantics. The patch has been validated by a functional test and by the boundary test documented at: https://gitlab.com/qemu-project/qemu/-/work_items/3436 Kane-Chen-AS (1): hw/misc/aspeed_sbc: Add bounds checking for OTP write operations hw/misc/aspeed_sbc.c | 14 +++++++++++--- hw/nvram/aspeed_otp.c | 13 ++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-28 5:52 [PATCH v1 0/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations Kane Chen @ 2026-04-28 5:52 ` Kane Chen 2026-04-30 11:03 ` Peter Maydell ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Kane Chen @ 2026-04-28 5:52 UTC (permalink / raw) To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here Cc: Troy Lee, Kane Chen, qemu-stable@nongnu.org, Cédric Le Goater There is a mismatch between the Aspeed OTP model and the Aspeed SBC model in how the guest-provided address is handled. aspeed_sbc_otp_prog() passes a word-indexed address directly to address_space_write() without converting it to a byte offset, whereas aspeed_otp_write() expects a byte offset and applies an additional shift (otp_addr << 2). This double-shift confusion means that an out-of-range word address can lead to a write beyond the allocated storage. Fix this by adding bounds checking on the word offset before converting to byte offset and passing to address_space_write(). This matches the existing bounds check in aspeed_sbc_otp_read(). Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> Cc: qemu-stable@nongnu.org Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 Reported-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> --- hw/misc/aspeed_sbc.c | 14 +++++++++++--- hw/nvram/aspeed_otp.c | 13 ++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c index 065e822e70..8b74dca13c 100644 --- a/hw/misc/aspeed_sbc.c +++ b/hw/misc/aspeed_sbc.c @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, MemTxResult ret; AspeedOTPState *otp = &s->otp; uint32_t value = s->regs[R_CAMP1]; + uint32_t otp_offset = otp_addr << 2; - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, - &value, sizeof(value)); + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { + qemu_log_mask(LOG_GUEST_ERROR, + "Invalid OTP addr 0x%x\n", + otp_addr); + return false; + } + + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, + &value, sizeof(value)); if (ret != MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Failed to write OTP memory, addr = %x\n", - otp_addr); + otp_offset); return false; } diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c index a60289000c..1a9d3841b8 100644 --- a/hw/nvram/aspeed_otp.c +++ b/hw/nvram/aspeed_otp.c @@ -57,12 +57,12 @@ static bool valid_program_data(uint32_t otp_addr, return has_programmable_bits != 0; } -static bool program_otpmem_data(void *opaque, uint32_t otp_addr, +static bool program_otpmem_data(void *opaque, hwaddr otp_offset, uint32_t prog_bit, uint32_t *value) { AspeedOTPState *s = opaque; + uint32_t otp_addr = otp_offset >> 2; bool is_odd = otp_addr & 1; - uint32_t otp_offset = otp_addr << 2; memcpy(value, s->storage + otp_offset, sizeof(uint32_t)); @@ -79,26 +79,25 @@ static bool program_otpmem_data(void *opaque, uint32_t otp_addr, return true; } -static void aspeed_otp_write(void *opaque, hwaddr otp_addr, +static void aspeed_otp_write(void *opaque, hwaddr otp_offset, uint64_t val, unsigned size) { AspeedOTPState *s = opaque; - uint32_t otp_offset, value; + uint32_t value; - if (!program_otpmem_data(s, otp_addr, val, &value)) { + if (!program_otpmem_data(s, otp_offset, val, &value)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to program data, value = %x, bit = %"PRIx64"\n", __func__, value, val); return; } - otp_offset = otp_addr << 2; memcpy(s->storage + otp_offset, &value, size); if (s->blk) { if (blk_pwrite(s->blk, otp_offset, size, &value, 0) < 0) { qemu_log_mask(LOG_GUEST_ERROR, - "%s: Failed to write %x to %x\n", + "%s: Failed to write %x to %"HWADDR_PRIx"\n", __func__, value, otp_offset); return; -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-28 5:52 ` [PATCH v1 1/1] " Kane Chen @ 2026-04-30 11:03 ` Peter Maydell 2026-04-30 13:48 ` 回覆: " Kane Chen 2026-04-30 17:56 ` Cédric Le Goater 2026-04-30 17:26 ` Cédric Le Goater 2026-05-14 18:48 ` Michael Tokarev 2 siblings, 2 replies; 10+ messages in thread From: Peter Maydell @ 2026-04-30 11:03 UTC (permalink / raw) To: Kane Chen Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On Tue, 28 Apr 2026 at 06:53, Kane Chen <kane_chen@aspeedtech.com> wrote: > > There is a mismatch between the Aspeed OTP model and the Aspeed SBC > model in how the guest-provided address is handled. > aspeed_sbc_otp_prog() passes a word-indexed address directly > to address_space_write() without converting it to a byte offset, > whereas aspeed_otp_write() expects a byte offset and applies an > additional shift (otp_addr << 2). This double-shift confusion means > that an out-of-range word address can lead to a write beyond the > allocated storage. > > Fix this by adding bounds checking on the word offset before > converting to byte offset and passing to address_space_write(). > This matches the existing bounds check in aspeed_sbc_otp_read(). > > Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > Cc: qemu-stable@nongnu.org > Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Cédric Le Goater <clg@redhat.com> > Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> > --- > hw/misc/aspeed_sbc.c | 14 +++++++++++--- > hw/nvram/aspeed_otp.c | 13 ++++++------- > 2 files changed, 17 insertions(+), 10 deletions(-) > > diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c > index 065e822e70..8b74dca13c 100644 > --- a/hw/misc/aspeed_sbc.c > +++ b/hw/misc/aspeed_sbc.c > @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, > MemTxResult ret; > AspeedOTPState *otp = &s->otp; > uint32_t value = s->regs[R_CAMP1]; > + uint32_t otp_offset = otp_addr << 2; > > - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, > - &value, sizeof(value)); > + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { > + qemu_log_mask(LOG_GUEST_ERROR, > + "Invalid OTP addr 0x%x\n", > + otp_addr); > + return false; > + } > + > + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, > + &value, sizeof(value)); > if (ret != MEMTX_OK) { > qemu_log_mask(LOG_GUEST_ERROR, > "Failed to write OTP memory, addr = %x\n", > - otp_addr); > + otp_offset); I would stick to reporting otp_addr here: - it's the value the guest actually writes - it matches the logging for "invalid OTP addr above" - it matches what aspeed_sbc_otp_read() logs in the equivalent case Otherwise Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM ^ permalink raw reply [flat|nested] 10+ messages in thread
* 回覆: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-30 11:03 ` Peter Maydell @ 2026-04-30 13:48 ` Kane Chen 2026-04-30 17:56 ` Cédric Le Goater 1 sibling, 0 replies; 10+ messages in thread From: Kane Chen @ 2026-04-30 13:48 UTC (permalink / raw) To: Peter Maydell Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater [-- Attachment #1: Type: text/plain, Size: 3556 bytes --] Hi Peter, Thanks for your review and feedback. I will update the logging accordingly and submit a v2 patch. Best Regards, Kane ________________________________ 寄件者: Peter Maydell <peter.maydell@linaro.org> 寄件日期: 2026年4月30日 下午 07:03 收件者: Kane Chen <kane_chen@aspeedtech.com> 副本: Cédric Le Goater <clg@kaod.org>; Steven Lee <steven_lee@aspeedtech.com>; Troy Lee <leetroy@gmail.com>; Jamin Lin <jamin_lin@aspeedtech.com>; Andrew Jeffery <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>; open list:ASPEED BMCs <qemu-arm@nongnu.org>; open list:All patches CC here <qemu-devel@nongnu.org>; Troy Lee <troy_lee@aspeedtech.com>; qemu-stable@nongnu.org <qemu-stable@nongnu.org>; Cédric Le Goater <clg@redhat.com> 主旨: Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations On Tue, 28 Apr 2026 at 06:53, Kane Chen <kane_chen@aspeedtech.com> wrote: > > There is a mismatch between the Aspeed OTP model and the Aspeed SBC > model in how the guest-provided address is handled. > aspeed_sbc_otp_prog() passes a word-indexed address directly > to address_space_write() without converting it to a byte offset, > whereas aspeed_otp_write() expects a byte offset and applies an > additional shift (otp_addr << 2). This double-shift confusion means > that an out-of-range word address can lead to a write beyond the > allocated storage. > > Fix this by adding bounds checking on the word offset before > converting to byte offset and passing to address_space_write(). > This matches the existing bounds check in aspeed_sbc_otp_read(). > > Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > Cc: qemu-stable@nongnu.org > Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Cédric Le Goater <clg@redhat.com> > Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> > --- > hw/misc/aspeed_sbc.c | 14 +++++++++++--- > hw/nvram/aspeed_otp.c | 13 ++++++------- > 2 files changed, 17 insertions(+), 10 deletions(-) > > diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c > index 065e822e70..8b74dca13c 100644 > --- a/hw/misc/aspeed_sbc.c > +++ b/hw/misc/aspeed_sbc.c > @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, > MemTxResult ret; > AspeedOTPState *otp = &s->otp; > uint32_t value = s->regs[R_CAMP1]; > + uint32_t otp_offset = otp_addr << 2; > > - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, > - &value, sizeof(value)); > + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { > + qemu_log_mask(LOG_GUEST_ERROR, > + "Invalid OTP addr 0x%x\n", > + otp_addr); > + return false; > + } > + > + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, > + &value, sizeof(value)); > if (ret != MEMTX_OK) { > qemu_log_mask(LOG_GUEST_ERROR, > "Failed to write OTP memory, addr = %x\n", > - otp_addr); > + otp_offset); I would stick to reporting otp_addr here: - it's the value the guest actually writes - it matches the logging for "invalid OTP addr above" - it matches what aspeed_sbc_otp_read() logs in the equivalent case Otherwise Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM [-- Attachment #2: Type: text/html, Size: 6726 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-30 11:03 ` Peter Maydell 2026-04-30 13:48 ` 回覆: " Kane Chen @ 2026-04-30 17:56 ` Cédric Le Goater 2026-05-04 5:56 ` Kane Chen 1 sibling, 1 reply; 10+ messages in thread From: Cédric Le Goater @ 2026-04-30 17:56 UTC (permalink / raw) To: Peter Maydell, Kane Chen Cc: Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On 4/30/26 13:03, Peter Maydell wrote: > On Tue, 28 Apr 2026 at 06:53, Kane Chen <kane_chen@aspeedtech.com> wrote: >> >> There is a mismatch between the Aspeed OTP model and the Aspeed SBC >> model in how the guest-provided address is handled. >> aspeed_sbc_otp_prog() passes a word-indexed address directly >> to address_space_write() without converting it to a byte offset, >> whereas aspeed_otp_write() expects a byte offset and applies an >> additional shift (otp_addr << 2). This double-shift confusion means >> that an out-of-range word address can lead to a write beyond the >> allocated storage. >> >> Fix this by adding bounds checking on the word offset before >> converting to byte offset and passing to address_space_write(). >> This matches the existing bounds check in aspeed_sbc_otp_read(). >> >> Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> >> Cc: qemu-stable@nongnu.org >> Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") >> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 >> Reported-by: Peter Maydell <peter.maydell@linaro.org> >> Signed-off-by: Cédric Le Goater <clg@redhat.com> >> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> >> --- >> hw/misc/aspeed_sbc.c | 14 +++++++++++--- >> hw/nvram/aspeed_otp.c | 13 ++++++------- >> 2 files changed, 17 insertions(+), 10 deletions(-) >> >> diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c >> index 065e822e70..8b74dca13c 100644 >> --- a/hw/misc/aspeed_sbc.c >> +++ b/hw/misc/aspeed_sbc.c >> @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, >> MemTxResult ret; >> AspeedOTPState *otp = &s->otp; >> uint32_t value = s->regs[R_CAMP1]; >> + uint32_t otp_offset = otp_addr << 2; >> >> - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, >> - &value, sizeof(value)); >> + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { >> + qemu_log_mask(LOG_GUEST_ERROR, >> + "Invalid OTP addr 0x%x\n", >> + otp_addr); >> + return false; >> + } >> + >> + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, >> + &value, sizeof(value)); >> if (ret != MEMTX_OK) { >> qemu_log_mask(LOG_GUEST_ERROR, >> "Failed to write OTP memory, addr = %x\n", >> - otp_addr); >> + otp_offset); > > I would stick to reporting otp_addr here: > - it's the value the guest actually writes > - it matches the logging for "invalid OTP addr above" > - it matches what aspeed_sbc_otp_read() logs in the equivalent case > > Otherwise > Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Applied to https://github.com/legoater/qemu aspeed-next with this change. Peter, Feel free to pick the change if needed. Thanks, C. ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-30 17:56 ` Cédric Le Goater @ 2026-05-04 5:56 ` Kane Chen 0 siblings, 0 replies; 10+ messages in thread From: Kane Chen @ 2026-05-04 5:56 UTC (permalink / raw) To: Cédric Le Goater, Peter Maydell Cc: Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater > -----Original Message----- > From: Cédric Le Goater <clg@kaod.org> > Sent: Friday, May 1, 2026 1:57 AM > To: Peter Maydell <peter.maydell@linaro.org>; Kane Chen > <kane_chen@aspeedtech.com> > Cc: Steven Lee <steven_lee@aspeedtech.com>; Troy Lee > <leetroy@gmail.com>; Jamin Lin <jamin_lin@aspeedtech.com>; Andrew > Jeffery <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>; open > list:ASPEED BMCs <qemu-arm@nongnu.org>; open list:All patches CC here > <qemu-devel@nongnu.org>; Troy Lee <troy_lee@aspeedtech.com>; > qemu-stable@nongnu.org; Cédric Le Goater <clg@redhat.com> > Subject: Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP > write operations > > On 4/30/26 13:03, Peter Maydell wrote: > > On Tue, 28 Apr 2026 at 06:53, Kane Chen <kane_chen@aspeedtech.com> > wrote: > >> > >> There is a mismatch between the Aspeed OTP model and the Aspeed SBC > >> model in how the guest-provided address is handled. > >> aspeed_sbc_otp_prog() passes a word-indexed address directly to > >> address_space_write() without converting it to a byte offset, whereas > >> aspeed_otp_write() expects a byte offset and applies an additional > >> shift (otp_addr << 2). This double-shift confusion means that an > >> out-of-range word address can lead to a write beyond the allocated > >> storage. > >> > >> Fix this by adding bounds checking on the word offset before > >> converting to byte offset and passing to address_space_write(). > >> This matches the existing bounds check in aspeed_sbc_otp_read(). > >> > >> Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > >> Cc: qemu-stable@nongnu.org > >> Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller > >> model") > >> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 > >> Reported-by: Peter Maydell <peter.maydell@linaro.org> > >> Signed-off-by: Cédric Le Goater <clg@redhat.com> > >> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> > >> --- > >> hw/misc/aspeed_sbc.c | 14 +++++++++++--- > >> hw/nvram/aspeed_otp.c | 13 ++++++------- > >> 2 files changed, 17 insertions(+), 10 deletions(-) > >> > >> diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c index > >> 065e822e70..8b74dca13c 100644 > >> --- a/hw/misc/aspeed_sbc.c > >> +++ b/hw/misc/aspeed_sbc.c > >> @@ -159,13 +159,21 @@ static bool > aspeed_sbc_otp_prog(AspeedSBCState *s, > >> MemTxResult ret; > >> AspeedOTPState *otp = &s->otp; > >> uint32_t value = s->regs[R_CAMP1]; > >> + uint32_t otp_offset = otp_addr << 2; > >> > >> - ret = address_space_write(&otp->as, otp_addr, > MEMTXATTRS_UNSPECIFIED, > >> - &value, sizeof(value)); > >> + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { > >> + qemu_log_mask(LOG_GUEST_ERROR, > >> + "Invalid OTP addr 0x%x\n", > >> + otp_addr); > >> + return false; > >> + } > >> + > >> + ret = address_space_write(&otp->as, otp_offset, > MEMTXATTRS_UNSPECIFIED, > >> + &value, sizeof(value)); > >> if (ret != MEMTX_OK) { > >> qemu_log_mask(LOG_GUEST_ERROR, > >> "Failed to write OTP memory, addr = %x\n", > >> - otp_addr); > >> + otp_offset); > > > > I would stick to reporting otp_addr here: > > - it's the value the guest actually writes > > - it matches the logging for "invalid OTP addr above" > > - it matches what aspeed_sbc_otp_read() logs in the equivalent case > > > > Otherwise > > Reviewed-by: Peter Maydell <peter.maydell@linaro.org> > > > > Applied to > > https://github.com/legoater/qemu aspeed-next > > with this change. > > Peter, > > Feel free to pick the change if needed. > > Thanks, > > C. Hi Cédric/Peter, Thanks for your review and comments. Currently, the naming of otp_addr and otp_offset is inconsistent, as both are used to represent the user-provided address. For example, when implementing the OTP module, I followed the naming convention used in the write operation (see the link below for reference): https://github.com/AspeedTech-BMC/zephyr/blob/aspeed-main-v3.7.0/drivers/misc/aspeed/otp_shell.c#L239 However, in the read path, the code uses the term offset instead (see below): https://github.com/AspeedTech-BMC/zephyr/blob/aspeed-main-v3.7.0/drivers/misc/aspeed/otp_shell.c#L150 To improve consistency, we could align the naming with otp_offset, following the read path convention. However, I'm not certain if this would be more intuitive. Please let me know if you have any further suggestions regarding the otp_addr / otp_offset naming. Best Regards, Kane ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-28 5:52 ` [PATCH v1 1/1] " Kane Chen 2026-04-30 11:03 ` Peter Maydell @ 2026-04-30 17:26 ` Cédric Le Goater 2026-04-30 17:47 ` Peter Maydell 2026-05-14 18:48 ` Michael Tokarev 2 siblings, 1 reply; 10+ messages in thread From: Cédric Le Goater @ 2026-04-30 17:26 UTC (permalink / raw) To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here Cc: Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On 4/28/26 07:52, Kane Chen wrote: > There is a mismatch between the Aspeed OTP model and the Aspeed SBC > model in how the guest-provided address is handled. > aspeed_sbc_otp_prog() passes a word-indexed address directly > to address_space_write() without converting it to a byte offset, > whereas aspeed_otp_write() expects a byte offset and applies an > additional shift (otp_addr << 2). This double-shift confusion means > that an out-of-range word address can lead to a write beyond the > allocated storage. > > Fix this by adding bounds checking on the word offset before > converting to byte offset and passing to address_space_write(). > This matches the existing bounds check in aspeed_sbc_otp_read(). > > Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > Cc: qemu-stable@nongnu.org > Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 > Reported-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Cédric Le Goater <clg@redhat.com> > Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> > --- > hw/misc/aspeed_sbc.c | 14 +++++++++++--- > hw/nvram/aspeed_otp.c | 13 ++++++------- > 2 files changed, 17 insertions(+), 10 deletions(-) > > diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c > index 065e822e70..8b74dca13c 100644 > --- a/hw/misc/aspeed_sbc.c > +++ b/hw/misc/aspeed_sbc.c > @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, > MemTxResult ret; > AspeedOTPState *otp = &s->otp; > uint32_t value = s->regs[R_CAMP1]; > + uint32_t otp_offset = otp_addr << 2; > > - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, > - &value, sizeof(value)); > + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { > + qemu_log_mask(LOG_GUEST_ERROR, > + "Invalid OTP addr 0x%x\n", > + otp_addr); This log event could be on one line. > + return false; > + } > + > + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, > + &value, sizeof(value)); > if (ret != MEMTX_OK) { > qemu_log_mask(LOG_GUEST_ERROR, > "Failed to write OTP memory, addr = %x\n", > - otp_addr); > + otp_offset); > return false; > } > > diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c > index a60289000c..1a9d3841b8 100644 > --- a/hw/nvram/aspeed_otp.c > +++ b/hw/nvram/aspeed_otp.c > @@ -57,12 +57,12 @@ static bool valid_program_data(uint32_t otp_addr, > return has_programmable_bits != 0; > } > > -static bool program_otpmem_data(void *opaque, uint32_t otp_addr, > +static bool program_otpmem_data(void *opaque, hwaddr otp_offset, > uint32_t prog_bit, uint32_t *value) > { > AspeedOTPState *s = opaque; > + uint32_t otp_addr = otp_offset >> 2; I think 'opt_addr' is a bit confusing. It's a word offset. valid_program_data() could also use an 'otp_offset' arg and I would introduce a small inline helper to replace variable 'is_odd' Thanks, C. > bool is_odd = otp_addr & 1; > - uint32_t otp_offset = otp_addr << 2; > > memcpy(value, s->storage + otp_offset, sizeof(uint32_t)); > > @@ -79,26 +79,25 @@ static bool program_otpmem_data(void *opaque, uint32_t otp_addr, > return true; > } > > -static void aspeed_otp_write(void *opaque, hwaddr otp_addr, > +static void aspeed_otp_write(void *opaque, hwaddr otp_offset, > uint64_t val, unsigned size) > { > AspeedOTPState *s = opaque; > - uint32_t otp_offset, value; > + uint32_t value; > > - if (!program_otpmem_data(s, otp_addr, val, &value)) { > + if (!program_otpmem_data(s, otp_offset, val, &value)) { > qemu_log_mask(LOG_GUEST_ERROR, > "%s: Failed to program data, value = %x, bit = %"PRIx64"\n", > __func__, value, val); > return; > } > > - otp_offset = otp_addr << 2; > memcpy(s->storage + otp_offset, &value, size); > > if (s->blk) { > if (blk_pwrite(s->blk, otp_offset, size, &value, 0) < 0) { > qemu_log_mask(LOG_GUEST_ERROR, > - "%s: Failed to write %x to %x\n", > + "%s: Failed to write %x to %"HWADDR_PRIx"\n", > __func__, value, otp_offset); > > return; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-30 17:26 ` Cédric Le Goater @ 2026-04-30 17:47 ` Peter Maydell 2026-04-30 17:54 ` Cédric Le Goater 0 siblings, 1 reply; 10+ messages in thread From: Peter Maydell @ 2026-04-30 17:47 UTC (permalink / raw) To: Cédric Le Goater Cc: Kane Chen, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On Thu, 30 Apr 2026 at 18:26, Cédric Le Goater <clg@kaod.org> wrote: > > On 4/28/26 07:52, Kane Chen wrote: > > There is a mismatch between the Aspeed OTP model and the Aspeed SBC > > model in how the guest-provided address is handled. > > aspeed_sbc_otp_prog() passes a word-indexed address directly > > to address_space_write() without converting it to a byte offset, > > whereas aspeed_otp_write() expects a byte offset and applies an > > additional shift (otp_addr << 2). This double-shift confusion means > > that an out-of-range word address can lead to a write beyond the > > allocated storage. > > > > Fix this by adding bounds checking on the word offset before > > converting to byte offset and passing to address_space_write(). > > This matches the existing bounds check in aspeed_sbc_otp_read(). > > > > Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > > Cc: qemu-stable@nongnu.org > > Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 > > Reported-by: Peter Maydell <peter.maydell@linaro.org> > > Signed-off-by: Cédric Le Goater <clg@redhat.com> > > Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> > > --- > > hw/misc/aspeed_sbc.c | 14 +++++++++++--- > > hw/nvram/aspeed_otp.c | 13 ++++++------- > > 2 files changed, 17 insertions(+), 10 deletions(-) > > > > diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c > > index 065e822e70..8b74dca13c 100644 > > --- a/hw/misc/aspeed_sbc.c > > +++ b/hw/misc/aspeed_sbc.c > > @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, > > MemTxResult ret; > > AspeedOTPState *otp = &s->otp; > > uint32_t value = s->regs[R_CAMP1]; > > + uint32_t otp_offset = otp_addr << 2; > > > > - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, > > - &value, sizeof(value)); > > + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { > > + qemu_log_mask(LOG_GUEST_ERROR, > > + "Invalid OTP addr 0x%x\n", > > + otp_addr); > > This log event could be on one line. > > > + return false; > > + } > > + > > + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, > > + &value, sizeof(value)); > > if (ret != MEMTX_OK) { > > qemu_log_mask(LOG_GUEST_ERROR, > > "Failed to write OTP memory, addr = %x\n", > > - otp_addr); > > + otp_offset); > > return false; > > } > > > > diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c > > index a60289000c..1a9d3841b8 100644 > > --- a/hw/nvram/aspeed_otp.c > > +++ b/hw/nvram/aspeed_otp.c > > @@ -57,12 +57,12 @@ static bool valid_program_data(uint32_t otp_addr, > > return has_programmable_bits != 0; > > } > > > > -static bool program_otpmem_data(void *opaque, uint32_t otp_addr, > > +static bool program_otpmem_data(void *opaque, hwaddr otp_offset, > > uint32_t prog_bit, uint32_t *value) > > { > > AspeedOTPState *s = opaque; > > + uint32_t otp_addr = otp_offset >> 2; > > I think 'opt_addr' is a bit confusing. It's a word offset. It's the variable name we're currently using for that meaning everywhere in these two devices, though. It might be better to keep that cleanup in a separate patch from this one. -- PMM ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-30 17:47 ` Peter Maydell @ 2026-04-30 17:54 ` Cédric Le Goater 0 siblings, 0 replies; 10+ messages in thread From: Cédric Le Goater @ 2026-04-30 17:54 UTC (permalink / raw) To: Peter Maydell Cc: Kane Chen, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here, Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On 4/30/26 19:47, Peter Maydell wrote: > On Thu, 30 Apr 2026 at 18:26, Cédric Le Goater <clg@kaod.org> wrote: >> >> On 4/28/26 07:52, Kane Chen wrote: >>> There is a mismatch between the Aspeed OTP model and the Aspeed SBC >>> model in how the guest-provided address is handled. >>> aspeed_sbc_otp_prog() passes a word-indexed address directly >>> to address_space_write() without converting it to a byte offset, >>> whereas aspeed_otp_write() expects a byte offset and applies an >>> additional shift (otp_addr << 2). This double-shift confusion means >>> that an out-of-range word address can lead to a write beyond the >>> allocated storage. >>> >>> Fix this by adding bounds checking on the word offset before >>> converting to byte offset and passing to address_space_write(). >>> This matches the existing bounds check in aspeed_sbc_otp_read(). >>> >>> Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> >>> Cc: qemu-stable@nongnu.org >>> Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") >>> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3436 >>> Reported-by: Peter Maydell <peter.maydell@linaro.org> >>> Signed-off-by: Cédric Le Goater <clg@redhat.com> >>> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com> >>> --- >>> hw/misc/aspeed_sbc.c | 14 +++++++++++--- >>> hw/nvram/aspeed_otp.c | 13 ++++++------- >>> 2 files changed, 17 insertions(+), 10 deletions(-) >>> >>> diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c >>> index 065e822e70..8b74dca13c 100644 >>> --- a/hw/misc/aspeed_sbc.c >>> +++ b/hw/misc/aspeed_sbc.c >>> @@ -159,13 +159,21 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s, >>> MemTxResult ret; >>> AspeedOTPState *otp = &s->otp; >>> uint32_t value = s->regs[R_CAMP1]; >>> + uint32_t otp_offset = otp_addr << 2; >>> >>> - ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED, >>> - &value, sizeof(value)); >>> + if (otp_addr >= OTP_TOTAL_DWORD_COUNT) { >>> + qemu_log_mask(LOG_GUEST_ERROR, >>> + "Invalid OTP addr 0x%x\n", >>> + otp_addr); >> >> This log event could be on one line. >> >>> + return false; >>> + } >>> + >>> + ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED, >>> + &value, sizeof(value)); >>> if (ret != MEMTX_OK) { >>> qemu_log_mask(LOG_GUEST_ERROR, >>> "Failed to write OTP memory, addr = %x\n", >>> - otp_addr); >>> + otp_offset); >>> return false; >>> } >>> >>> diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c >>> index a60289000c..1a9d3841b8 100644 >>> --- a/hw/nvram/aspeed_otp.c >>> +++ b/hw/nvram/aspeed_otp.c >>> @@ -57,12 +57,12 @@ static bool valid_program_data(uint32_t otp_addr, >>> return has_programmable_bits != 0; >>> } >>> >>> -static bool program_otpmem_data(void *opaque, uint32_t otp_addr, >>> +static bool program_otpmem_data(void *opaque, hwaddr otp_offset, >>> uint32_t prog_bit, uint32_t *value) >>> { >>> AspeedOTPState *s = opaque; >>> + uint32_t otp_addr = otp_offset >> 2; >> >> I think 'opt_addr' is a bit confusing. It's a word offset. > > It's the variable name we're currently using for that meaning > everywhere in these two devices, though. It might be better > to keep that cleanup in a separate patch from this one. OK. Let's do that. C. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations 2026-04-28 5:52 ` [PATCH v1 1/1] " Kane Chen 2026-04-30 11:03 ` Peter Maydell 2026-04-30 17:26 ` Cédric Le Goater @ 2026-05-14 18:48 ` Michael Tokarev 2 siblings, 0 replies; 10+ messages in thread From: Michael Tokarev @ 2026-05-14 18:48 UTC (permalink / raw) To: Kane Chen, Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs, open list:All patches CC here Cc: Troy Lee, qemu-stable@nongnu.org, Cédric Le Goater On 28.04.2026 08:52, Kane Chen wrote: > There is a mismatch between the Aspeed OTP model and the Aspeed SBC > model in how the guest-provided address is handled. > aspeed_sbc_otp_prog() passes a word-indexed address directly > to address_space_write() without converting it to a byte offset, > whereas aspeed_otp_write() expects a byte offset and applies an > additional shift (otp_addr << 2). This double-shift confusion means > that an out-of-range word address can lead to a write beyond the > allocated storage. > > Fix this by adding bounds checking on the word offset before > converting to byte offset and passing to address_space_write(). > This matches the existing bounds check in aspeed_sbc_otp_read(). > > Cc: Kane-Chen-AS <kane_chen@aspeedtech.com> > Cc: qemu-stable@nongnu.org > Fixes: 1a00754ccf15 ("hw/misc: Add Aspeed Secure Boot Controller model") FWIW (this change has already landed in the master branch, so it's cast in stone), I can't find this commit in my git clone of qemu repository. Neither hash ID nor the name. Is it this one maybe? https://marc.info/?l=qemu-arm&m=164500409921734, which is commit e1acf581c9 in qemu? It has a different commit message though. And this patch does not apply to 10.0.x, - in there, there's no hw/nvram/aspeed_otp.c (688a3dae78 hw/nvram/aspeed_otp: Add ASPEED OTP memory device model). I assume it's not needed for 10.0.x, but in that case, the Fixes: tag isn't even commit e1acf581c9. Thanks, /mjt ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-14 18:49 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-28 5:52 [PATCH v1 0/1] hw/misc/aspeed_sbc: Add bounds checking for OTP write operations Kane Chen 2026-04-28 5:52 ` [PATCH v1 1/1] " Kane Chen 2026-04-30 11:03 ` Peter Maydell 2026-04-30 13:48 ` 回覆: " Kane Chen 2026-04-30 17:56 ` Cédric Le Goater 2026-05-04 5:56 ` Kane Chen 2026-04-30 17:26 ` Cédric Le Goater 2026-04-30 17:47 ` Peter Maydell 2026-04-30 17:54 ` Cédric Le Goater 2026-05-14 18:48 ` Michael Tokarev
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.