Skip to content

Commit 6b38865

Browse files
authored
chore: guard localtxmonitor server against int overflows (#900)
Signed-off-by: Chris Gianelloni <[email protected]>
1 parent 1a91b95 commit 6b38865

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

protocol/localtxmonitor/messages.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 Blink Labs Software
1+
// Copyright 2025 Blink Labs Software
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package localtxmonitor
1616

1717
import (
1818
"fmt"
19+
"math"
1920

2021
"github.com/blinklabs-io/gouroboros/cbor"
2122
"github.com/blinklabs-io/gouroboros/protocol"
@@ -170,13 +171,21 @@ func (m *MsgReplyNextTx) UnmarshalCBOR(data []byte) error {
170171
if tmp == nil {
171172
return nil
172173
}
174+
messageType64 := tmp[0].(uint64)
175+
if messageType64 > math.MaxUint8 {
176+
return fmt.Errorf("message type integer overflow")
177+
}
173178
// We know what the value will be, but it doesn't hurt to use the actual value from the message
174-
m.MessageType = uint8(tmp[0].(uint64))
179+
m.MessageType = uint8(messageType64)
175180
// The ReplyNextTx message has a variable number of arguments
176181
if len(tmp) > 1 {
177182
txWrapper := tmp[1].([]interface{})
183+
eraId64 := txWrapper[0].(uint64)
184+
if eraId64 > math.MaxUint8 {
185+
return fmt.Errorf("era id integer overflow")
186+
}
178187
m.Transaction = MsgReplyNextTxTransaction{
179-
EraId: uint8(txWrapper[0].(uint64)),
188+
EraId: uint8(eraId64),
180189
Tx: txWrapper[1].(cbor.WrappedCbor).Bytes(),
181190
}
182191
}

protocol/localtxmonitor/server.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 Blink Labs Software
1+
// Copyright 2025 Blink Labs Software
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package localtxmonitor
1717
import (
1818
"encoding/hex"
1919
"fmt"
20+
"math"
2021

2122
"github.com/blinklabs-io/gouroboros/ledger"
2223
"github.com/blinklabs-io/gouroboros/protocol"
@@ -193,6 +194,9 @@ func (s *Server) handleNextTx() error {
193194
return nil
194195
}
195196
mempoolTx := s.mempoolTxs[s.mempoolNextTxIdx]
197+
if mempoolTx.EraId > math.MaxUint8 {
198+
return fmt.Errorf("integer overflow in era id")
199+
}
196200
newMsg := NewMsgReplyNextTx(uint8(mempoolTx.EraId), mempoolTx.Tx)
197201
if err := s.SendMessage(newMsg); err != nil {
198202
return err
@@ -213,10 +217,18 @@ func (s *Server) handleGetSizes() error {
213217
for _, tx := range s.mempoolTxs {
214218
totalTxSize += len(tx.Tx)
215219
}
220+
numTxs := len(s.mempoolTxs)
221+
// check for over/underflows
222+
if totalTxSize < 0 || totalTxSize > math.MaxUint32 {
223+
return fmt.Errorf("integrer overflow in total tx size")
224+
}
225+
if numTxs < 0 || numTxs > math.MaxUint32 {
226+
return fmt.Errorf("integrer overflow in tx count")
227+
}
216228
newMsg := NewMsgReplyGetSizes(
217229
s.mempoolCapacity,
218-
uint32(totalTxSize),
219-
uint32(len(s.mempoolTxs)),
230+
uint32(totalTxSize), // #nosec G115
231+
uint32(numTxs),
220232
)
221233
if err := s.SendMessage(newMsg); err != nil {
222234
return err

0 commit comments

Comments
 (0)