mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-15 01:25:00 +03:00
fix(amneziawg): bound what a handshake allocates and the tunnel MTU
Every handshake initiation builds Jc junk packets of Jmin..Jmax bytes and the I1-I5 signature packets, and the limits allowed the full uint32 range and lengths of any size, so one connection made the embedded device allocate without bound. The MTU reaches the device as an int32 and a wider value made it panic. Both ended the whole panel at the next connection, after every restart. Jc is now at most 128, Jmin/Jmax and each signature packet at most one 65535-byte datagram, and the MTU at most 65535. Saves refuse more, the device setup refuses rows stored before, and the stored MTU is capped where it is read. The form schemas carry the same limits.
This commit is contained in:
@@ -25,6 +25,10 @@ func buildClientUAPIConfig(inst amneziawg.OutboundInstance, opts DeviceOptions)
|
||||
}
|
||||
b.WriteString("replace_peers=true\n")
|
||||
|
||||
// Rows saved before these bounds existed would allocate without limit per handshake.
|
||||
if err := amneziawg.ValidateHandshakePreamble(inst.Obfuscation); err != nil {
|
||||
return "", err
|
||||
}
|
||||
o := inst.Obfuscation
|
||||
fmt.Fprintf(&b, "jc=%d\njmin=%d\njmax=%d\n", o.Jc, o.Jmin, o.Jmax)
|
||||
fmt.Fprintf(&b, "s1=%d\ns2=%d\ns3=%d\ns4=%d\n", o.S1, o.S2, o.S3, o.S4)
|
||||
|
||||
@@ -199,6 +199,10 @@ func buildUAPIConfig(inst amneziawg.Instance, opts DeviceOptions) (string, error
|
||||
// dropped instead of lingering from a previous IpcSet call.
|
||||
b.WriteString("replace_peers=true\n")
|
||||
|
||||
// Rows saved before these bounds existed would allocate without limit per handshake.
|
||||
if err := amneziawg.ValidateHandshakePreamble(inst.Obfuscation); err != nil {
|
||||
return "", err
|
||||
}
|
||||
o := inst.Obfuscation
|
||||
fmt.Fprintf(&b, "jc=%d\njmin=%d\njmax=%d\n", o.Jc, o.Jmin, o.Jmax)
|
||||
fmt.Fprintf(&b, "s1=%d\ns2=%d\ns3=%d\ns4=%d\n", o.S1, o.S2, o.S3, o.S4)
|
||||
|
||||
@@ -679,3 +679,16 @@ func TestBuildUAPIConfigClearedHeaderProtectionKeyIsSentAsZero(t *testing.T) {
|
||||
t.Fatalf("a configured key must not be emitted as zero, got:\n%s", withKey)
|
||||
}
|
||||
}
|
||||
|
||||
// A row stored before the handshake bounds existed must fail its own device setup instead
|
||||
// of allocating without limit at the next handshake, which ended the whole panel.
|
||||
func TestBuildUAPIConfigRefusesAStoredUnboundedPreamble(t *testing.T) {
|
||||
priv, _, err := wireguard.GenerateWireguardKeypair()
|
||||
if err != nil {
|
||||
t.Fatalf("generate keypair: %v", err)
|
||||
}
|
||||
inst := amneziawg.Instance{PrivateKey: priv, Obfuscation: amneziawg.Obfuscation31{Jc: 1 << 31, Jmin: 10, Jmax: 20}}
|
||||
if _, err := buildUAPIConfig(inst, DeviceOptions{}); err == nil {
|
||||
t.Fatal("a stored Jc of 2^31 reached the device")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user