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-newtmgr.git

commit 6f67ceebee820e159ec3b99fbf0fe37c1da93c3b
Author: Szymon Janc <[email protected]>
AuthorDate: Thu Oct 22 00:25:48 2026 +0200

    nmxact/nmxutil: Fix Fragment hang for non-positive MTU
    
    Fragment advanced its offset by mtu, so an mtu of 0 never terminated
    and kept appending empty fragments until memory ran out, and a
    negative mtu panicked with an out of range slice. The mtu comes from
    Sesn.MtuOut(), which can be 0 or negative, e.g. a BLE session whose
    ATT MTU is not known yet (AttMtu - 3) or a serial session configured
    with a very small MTU, so a request could hang newtmgr forever.
    
    Return the whole buffer as a single fragment when mtu <= 0. For
    datagram transports the transceiver already rejects such a request
    as "Request too big" before fragmenting; elsewhere the buffer is
    handed to the transport unfragmented, which can report an error,
    instead of hanging. An empty buffer still yields no fragments.
    
    Assisted-by: Claude:claude-opus-5-5
---
 nmxact/nmxutil/nmxutil.go      | 9 +++++++++
 nmxact/nmxutil/nmxutil_test.go | 5 +++++
 2 files changed, 14 insertions(+)

diff --git a/nmxact/nmxutil/nmxutil.go b/nmxact/nmxutil/nmxutil.go
index e917c34..fa25112 100644
--- a/nmxact/nmxutil/nmxutil.go
+++ b/nmxact/nmxutil/nmxutil.go
@@ -158,6 +158,15 @@ func StopAndDrainTimer(timer *time.Timer) {
 func Fragment(b []byte, mtu int) [][]byte {
        frags := [][]byte{}
 
+       // Without a usable MTU, do not fragment at all.  An mtu of 0 used to
+       // loop forever and a negative one used to panic.
+       if mtu <= 0 {
+               if len(b) > 0 {
+                       frags = append(frags, b)
+               }
+               return frags
+       }
+
        for off := 0; off < len(b); off += mtu {
                fragEnd := off + mtu
                if fragEnd > len(b) {
diff --git a/nmxact/nmxutil/nmxutil_test.go b/nmxact/nmxutil/nmxutil_test.go
index 13967cd..49526a4 100644
--- a/nmxact/nmxutil/nmxutil_test.go
+++ b/nmxact/nmxutil/nmxutil_test.go
@@ -44,6 +44,11 @@ func TestFragment(t *testing.T) {
                        [][]byte{{0, 1, 2, 3, 4}, {5, 6, 7, 8, 9}}},
                {"exact", data, 10, [][]byte{data}},
                {"larger mtu", data, 100, [][]byte{data}},
+
+               // No usable MTU: the buffer is not fragmented.
+               {"mtu 0", data, 0, [][]byte{data}},
+               {"negative mtu", data, -5, [][]byte{data}},
+               {"mtu 0 empty", []byte{}, 0, [][]byte{}},
        }
 
        for _, tt := range tests {

Reply via email to