Skip to content

Commit ee821dc

Browse files
authored
fix(ledger): guard againt int overflows (#901)
Signed-off-by: Chris Gianelloni <[email protected]>
1 parent 6b38865 commit ee821dc

File tree

18 files changed

+155
-22
lines changed

18 files changed

+155
-22
lines changed

ledger/allegra/allegra.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func (b *AllegraBlock) Era() common.Era {
9898

9999
func (b *AllegraBlock) Transactions() []common.Transaction {
100100
ret := make([]common.Transaction, len(b.TransactionBodies))
101+
// #nosec G115
101102
for idx := range b.TransactionBodies {
102103
ret[idx] = &AllegraTransaction{
103104
Body: b.TransactionBodies[idx],

ledger/alonzo/alonzo.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func (b *AlonzoBlock) Transactions() []common.Transaction {
106106
}
107107

108108
ret := make([]common.Transaction, len(b.TransactionBodies))
109+
// #nosec G115
109110
for idx := range b.TransactionBodies {
110111
ret[idx] = &AlonzoTransaction{
111112
Body: b.TransactionBodies[idx],

ledger/alonzo/pparams.go

Lines changed: 32 additions & 2 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.
@@ -15,10 +15,13 @@
1515
package alonzo
1616

1717
import (
18+
"math"
19+
20+
cardano "github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
21+
1822
"github.com/blinklabs-io/gouroboros/cbor"
1923
"github.com/blinklabs-io/gouroboros/ledger/common"
2024
"github.com/blinklabs-io/gouroboros/ledger/mary"
21-
"github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
2225
)
2326

2427
type AlonzoProtocolParameters struct {
@@ -115,6 +118,33 @@ func (u *AlonzoProtocolParameterUpdate) UnmarshalCBOR(data []byte) error {
115118
}
116119

117120
func (p *AlonzoProtocolParameters) Utxorpc() *cardano.PParams {
121+
// sanity check
122+
if p.A0.Num().Int64() > math.MaxInt32 ||
123+
p.A0.Denom().Int64() < 0 ||
124+
p.A0.Denom().Int64() > math.MaxUint32 {
125+
return nil
126+
}
127+
if p.Rho.Num().Int64() > math.MaxInt32 ||
128+
p.Rho.Denom().Int64() < 0 ||
129+
p.Rho.Denom().Int64() > math.MaxUint32 {
130+
return nil
131+
}
132+
if p.Tau.Num().Int64() > math.MaxInt32 ||
133+
p.Tau.Denom().Int64() < 0 ||
134+
p.Tau.Denom().Int64() > math.MaxUint32 {
135+
return nil
136+
}
137+
if p.ExecutionCosts.MemPrice.Num().Int64() > math.MaxInt32 ||
138+
p.ExecutionCosts.MemPrice.Denom().Int64() < 0 ||
139+
p.ExecutionCosts.MemPrice.Denom().Int64() > math.MaxUint32 {
140+
return nil
141+
}
142+
if p.ExecutionCosts.StepPrice.Num().Int64() > math.MaxInt32 ||
143+
p.ExecutionCosts.StepPrice.Denom().Int64() < 0 ||
144+
p.ExecutionCosts.StepPrice.Denom().Int64() > math.MaxUint32 {
145+
return nil
146+
}
147+
// #nosec G115
118148
return &cardano.PParams{
119149
CoinsPerUtxoByte: p.AdaPerUtxoByte,
120150
MaxTxSize: uint64(p.MaxTxSize),

ledger/babbage/babbage.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ func (b *BabbageBlock) Transactions() []common.Transaction {
107107
}
108108

109109
ret := make([]common.Transaction, len(b.TransactionBodies))
110+
// #nosec G115
110111
for idx := range b.TransactionBodies {
111112
ret[idx] = &BabbageTransaction{
112113
Body: b.TransactionBodies[idx],

ledger/babbage/pparams.go

Lines changed: 32 additions & 2 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.
@@ -15,10 +15,13 @@
1515
package babbage
1616

1717
import (
18+
"math"
19+
20+
cardano "github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
21+
1822
"github.com/blinklabs-io/gouroboros/cbor"
1923
"github.com/blinklabs-io/gouroboros/ledger/alonzo"
2024
"github.com/blinklabs-io/gouroboros/ledger/common"
21-
"github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
2225
)
2326

2427
// BabbageProtocolParameters represents the current Babbage protocol parameters as seen in local-state-query
@@ -154,6 +157,33 @@ func (u *BabbageProtocolParameterUpdate) UnmarshalCBOR(data []byte) error {
154157
}
155158

156159
func (p *BabbageProtocolParameters) Utxorpc() *cardano.PParams {
160+
// sanity check
161+
if p.A0.Num().Int64() > math.MaxInt32 ||
162+
p.A0.Denom().Int64() < 0 ||
163+
p.A0.Denom().Int64() > math.MaxUint32 {
164+
return nil
165+
}
166+
if p.Rho.Num().Int64() > math.MaxInt32 ||
167+
p.Rho.Denom().Int64() < 0 ||
168+
p.Rho.Denom().Int64() > math.MaxUint32 {
169+
return nil
170+
}
171+
if p.Tau.Num().Int64() > math.MaxInt32 ||
172+
p.Tau.Denom().Int64() < 0 ||
173+
p.Tau.Denom().Int64() > math.MaxUint32 {
174+
return nil
175+
}
176+
if p.ExecutionCosts.MemPrice.Num().Int64() > math.MaxInt32 ||
177+
p.ExecutionCosts.MemPrice.Denom().Int64() < 0 ||
178+
p.ExecutionCosts.MemPrice.Denom().Int64() > math.MaxUint32 {
179+
return nil
180+
}
181+
if p.ExecutionCosts.StepPrice.Num().Int64() > math.MaxInt32 ||
182+
p.ExecutionCosts.StepPrice.Denom().Int64() < 0 ||
183+
p.ExecutionCosts.StepPrice.Denom().Int64() > math.MaxUint32 {
184+
return nil
185+
}
186+
// #nosec G115
157187
return &cardano.PParams{
158188
CoinsPerUtxoByte: p.AdaPerUtxoByte,
159189
MaxTxSize: uint64(p.MaxTxSize),

ledger/byron/byron.go

Lines changed: 5 additions & 1 deletion
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 byron
1717
import (
1818
"encoding/hex"
1919
"fmt"
20+
"math"
2021

2122
"github.com/blinklabs-io/gouroboros/cbor"
2223
"github.com/blinklabs-io/gouroboros/ledger/common"
@@ -314,6 +315,9 @@ func NewByronTransactionInput(hash string, idx int) ByronTransactionInput {
314315
if err != nil {
315316
panic(fmt.Sprintf("failed to decode transaction hash: %s", err))
316317
}
318+
if idx < 0 || idx > math.MaxUint32 {
319+
panic("index out of range")
320+
}
317321
return ByronTransactionInput{
318322
TxId: common.Blake2b256(tmpHash),
319323
OutputIndex: uint32(idx),

ledger/common/certs.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ func (c *CertificateWrapper) UnmarshalCBOR(data []byte) error {
102102
if _, err := cbor.Decode(data, tmpCert); err != nil {
103103
return err
104104
}
105-
c.Type = uint(certType)
105+
// certType is known within uint range
106+
c.Type = uint(certType) // #nosec G115
106107
c.Certificate = tmpCert
107108
return nil
108109
}
@@ -355,6 +356,7 @@ func (c *PoolRegistrationCertificate) Utxorpc() *utxorpc.Certificate {
355356
VrfKeyhash: c.VrfKeyHash[:],
356357
Pledge: c.Pledge,
357358
Cost: c.Cost,
359+
// #nosec G115
358360
Margin: &utxorpc.RationalNumber{
359361
Numerator: int32(c.Margin.Num().Int64()),
360362
Denominator: uint32(c.Margin.Denom().Uint64()),
@@ -484,13 +486,17 @@ func (c *MoveInstantaneousRewardsCertificate) Utxorpc() *utxorpc.Certificate {
484486
tmpMirTargets,
485487
&utxorpc.MirTarget{
486488
StakeCredential: stakeCred.Utxorpc(),
487-
DeltaCoin: int64(deltaCoin),
489+
// potential integer overflow
490+
// #nosec G115
491+
DeltaCoin: int64(deltaCoin),
488492
},
489493
)
490494
}
491495
return &utxorpc.Certificate{
492496
Certificate: &utxorpc.Certificate_MirCert{
493497
MirCert: &utxorpc.MirCert{
498+
// potential integer overflow
499+
// #nosec G115
494500
From: utxorpc.MirSource(c.Reward.Source),
495501
To: tmpMirTargets,
496502
OtherPot: c.Reward.OtherPot,

ledger/common/gov.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ func (g *GovActionWrapper) UnmarshalCBOR(data []byte) error {
113113
if _, err := cbor.Decode(data, tmpAction); err != nil {
114114
return err
115115
}
116-
g.Type = uint(actionType)
116+
// action type is known within uint range
117+
g.Type = uint(actionType) // #nosec G115
117118
g.Action = tmpAction
118119
return nil
119120
}

ledger/common/nonce.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ func (n *Nonce) UnmarshalCBOR(data []byte) error {
3838
if err != nil {
3939
return err
4040
}
41-
42-
n.Type = uint(nonceType)
43-
41+
// nonce type is known within uint range
42+
n.Type = uint(nonceType) // #nosec G115
4443
switch nonceType {
4544
case NonceTypeNeutral:
4645
// Value uses default value

ledger/conway/conway.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func (b *ConwayBlock) Transactions() []common.Transaction {
106106
}
107107

108108
ret := make([]common.Transaction, len(b.TransactionBodies))
109+
// #nosec G115
109110
for idx := range b.TransactionBodies {
110111
ret[idx] = &ConwayTransaction{
111112
Body: b.TransactionBodies[idx],

0 commit comments

Comments
 (0)