laundervictim.gno
2.89 Kb · 78 lines
1// Package laundervictim is the "victim" realm in the launder-game
2// tests. It exposes a package-level g that an attacker tries to
3// mutate by various means. Two shapes are exposed:
4//
5// - gVal is `launderpkg.Object` (value type).
6// - gPtr is `*launderpkg.Object` (pointer to a fresh Object).
7//
8// Both are allocated at init under this realm's context, so their
9// PkgID stamp is /r/.../laundervictim. The attacker's job is to make
10// the stamp not match m.Realm at the write site — by laundering the
11// stamp, capturing the value, or exploiting a borrow-rule shift.
12package laundervictim
13
14import "gno.land/p/demo/tests/launderpkg"
15
16var (
17 gVal launderpkg.Object
18 gPtr *launderpkg.Object
19 // gImm is an Immutable: same layout as Object but no mutator
20 // method in /p/launderpkg. Victim exposes a pointer to it,
21 // intending "callers can read but not write."
22 gImm *launderpkg.Immutable
23 // gBuf is a victim-owned byte buffer (real, /r/laundervictim-stamped
24 // after init). Used to probe whether a stdlib method (e.g.
25 // base64.Encode) can be tricked into writing the victim's own buffer
26 // when an attacker passes it as an out-parameter.
27 gBuf []byte
28)
29
30func init() {
31 gVal = launderpkg.Object{Field: "original-val"}
32 gPtr = &launderpkg.Object{Field: "original-ptr"}
33 gImm = &launderpkg.Immutable{Field: "original-imm"}
34 gBuf = []byte("original-buffer!")
35}
36
37// GetVal returns g by VALUE (caller gets a copy).
38func GetVal() launderpkg.Object { return gVal }
39
40// GetPtr returns the pointer to gPtr's underlying Object. The
41// returned pointer aliases the victim's persisted state.
42func GetPtr() *launderpkg.Object { return gPtr }
43
44// GetValAddr returns &gVal — a pointer to the value-typed slot.
45// The returned pointer aliases the victim's persisted state.
46func GetValAddr() *launderpkg.Object { return &gVal }
47
48// GetImm returns the pointer to gImm — a *Immutable, which has no
49// mutator method in /p/launderpkg. Victim's intent: callers can read
50// but not write.
51func GetImm() *launderpkg.Immutable { return gImm }
52
53// GetBuf returns the victim's own byte buffer. The returned slice
54// aliases the victim's persisted backing array (/r/laundervictim-stamped).
55func GetBuf() []byte { return gBuf }
56
57// ReadVal / ReadPtr / ReadImm / ReadBuf report the current values for
58// after-attack verification.
59func ReadVal() string { return gVal.Field }
60func ReadPtr() string { return gPtr.Field }
61func ReadImm() string { return gImm.Field }
62func ReadBuf() string { return string(gBuf) }
63
64// Exploiter is the interface the victim accepts. The attacker
65// supplies an implementation; the victim invokes Something(g)
66// passing its own g. This is the "victim hands attacker the data"
67// vector.
68type Exploiter interface {
69 Something(launderpkg.Object)
70 SomethingPtr(*launderpkg.Object)
71}
72
73// Invoke calls the attacker's methods passing the victim's g by both
74// value and by pointer.
75func Invoke(e Exploiter) {
76 e.Something(gVal)
77 e.SomethingPtr(gPtr)
78}