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 {
