This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git

commit d0df0ce8425c4f7c0a8e0f5e9083b150c6e8aa68
Author: Szymon Janc <[email protected]>
AuthorDate: Mon Oct 19 17:53:48 2026 +0200

    newt/mfg: Fix panic with meta region below base address
    
    The meta region offset was calculated relative to the base address
    given with --base-address without any checks. If the meta flash area
    was located below it, e.g. in an area on another flash device at offset
    0 while the image used base address 0x08000000, the negative offset
    caused a slice bounds panic in mynewt-artifact when generating the
    image.
    
    Take the meta area's device into account when determining the flash
    device of the image, and report an error if the meta region offset is
    below the base address.
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/mfg/build.go      |  8 ++++++++
 newt/mfg/build_test.go | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/newt/mfg/build.go b/newt/mfg/build.go
index 66886a27..721ef658 100644
--- a/newt/mfg/build.go
+++ b/newt/mfg/build.go
@@ -428,6 +428,9 @@ func (mb *MfgBuilder) calcDevice() (int, error) {
        for _, r := range mb.Raws {
                deviceMap[r.Area.Device] = struct{}{}
        }
+       if mb.Meta != nil {
+               deviceMap[mb.Meta.Area.Device] = struct{}{}
+       }
 
        devices := make([]int, 0, len(deviceMap))
        for d, _ := range deviceMap {
@@ -631,6 +634,11 @@ func (mb *MfgBuilder) Build() (mfg.Mfg, error) {
                }
                metap = &meta
                metaOff = mb.metaOffset(meta)
+               if metaOff < 0 {
+                       return mfg.Mfg{}, util.FmtNewtError(
+                               "meta region in flash area \"%s\" is located 
below "+
+                                       "base address 0x%x", mb.Meta.Area.Name, 
mb.BaseAddress)
+               }
        }
 
        return mfg.Mfg{
diff --git a/newt/mfg/build_test.go b/newt/mfg/build_test.go
index 5db104a2..ebd36284 100644
--- a/newt/mfg/build_test.go
+++ b/newt/mfg/build_test.go
@@ -121,3 +121,43 @@ func TestDetectOverlapsMeta(t *testing.T) {
                t.Fatal("overlap of meta region not detected")
        }
 }
+
+// The meta region must be on the same flash device as the rest of the
+// image.
+func TestCalcDeviceMeta(t *testing.T) {
+       area := testAreaBoot
+       area.Device = 1
+       meta := &MfgBuildMeta{
+               Area: area,
+               Hash: true,
+       }
+
+       mb := testBuilder(meta, testRaw(t, testAreaImage, 0, 0x100))
+       if _, err := mb.calcDevice(); err == nil {
+               t.Fatal("meta region on another device not detected")
+       }
+}
+
+// The meta region must not be located below the base address.
+func TestBuildMetaBelowBase(t *testing.T) {
+       area := testAreaImage
+       area.Offset = 0x08000000
+       meta := &MfgBuildMeta{
+               Area: testAreaBoot,
+               Hash: true,
+       }
+
+       mb := testBuilder(meta, testRaw(t, area, 0, 0x100))
+       mb.BaseAddress = 0x08000000
+
+       m, err := mb.Build()
+       if err == nil {
+               defer func() {
+                       if r := recover(); r != nil {
+                               t.Fatalf("panic: %v", r)
+                       }
+               }()
+               m.Bytes(0xff)
+               t.Fatal("meta region below base address not detected")
+       }
+}

Reply via email to