Documentation ¶
Overview ¶
Package protectmem provides functions to allocate memory that can be protected after allocation. Protecting allows removing Write access or Read access after the memory has been allocated.
This package is not intended to be used in production code, but is intended for unit tests.
Example (AllocateAndProtect) ¶
package main import ( "fmt" "unsafe" "github.com/prashantv/protectmem" ) func main() { type S struct { F1 string F2 string } // Allocate S using protectmem sAlloc := protectmem.Allocate(unsafe.Sizeof(S{})) sPtr := (*S)(sAlloc.Ptr()) // sPtr can be used as a normal Go struct sPtr.F1 = "f1" sPtr.F2 = "more data" // Now you can protect the memory from being modified sAlloc.Protect(protectmem.Read) // Reads are fine: _ = sPtr.F1 // Writes will cause a fault sPtr.F1 = "this will fail" // You can also protect from both reads and writes sAlloc.Protect(protectmem.None) // Even reads will fail. fmt.Println(sPtr.F1) }
Output:
Example (AllocateSliceAndProtect) ¶
package main import ( "fmt" "github.com/prashantv/protectmem" ) func main() { var ints []int // Initializes ints to be a slice with 10 capacity, 0 length. alloc := protectmem.AllocateSlice(&ints, 10) for i := 0; i < cap(ints); i++ { ints = append(ints, i) } // Make the slice read only, can still print the slice fine. alloc.Protect(protectmem.Read) fmt.Println(ints) // ints cannot be written to, the following would crash ints[1] = 5 // We can also protect the slice from any reads or writes alloc.Protect(protectmem.None) // Now even a read will fail fmt.Println(ints) }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Access ¶
type Access int
Access returns the access level for an allocation.
List of different access bits that can be ORed together.
type Allocation ¶
type Allocation struct {
// contains filtered or unexported fields
}
Allocation represents an allocation created by this package that can be protected.
func Allocate ¶
func Allocate(size uintptr) *Allocation
Allocate allocates space with the specified size that can be protected in future. The size is typically specified using unsafe.Sizeof
Example ¶
package main import ( "net" "unsafe" "github.com/prashantv/protectmem" ) func main() { ipAlloc := protectmem.Allocate(unsafe.Sizeof(net.IPAddr{})) ip := (*net.IPAddr)(ipAlloc.Ptr()) _, _ = ipAlloc, ip }
Output:
func AllocateSlice ¶
func AllocateSlice(slicePtr interface{}, capacity int) *Allocation
AllocateSlice allocates the specified capacity slice and modifies the given ptr.
Example ¶
package main import ( "fmt" "github.com/prashantv/protectmem" ) func main() { var strings []string alloc := protectmem.AllocateSlice(&strings, 100) _ = alloc fmt.Println("length", len(strings), "cap", cap(strings)) }
Output: length 0 cap 100
func (*Allocation) Access ¶
func (a *Allocation) Access() Access
Access returns the current access level for the page.
Example ¶
package main import ( "fmt" "net" "unsafe" "github.com/prashantv/protectmem" ) func main() { alloc := protectmem.Allocate(unsafe.Sizeof(net.IPAddr{})) // Access returns the permissions for the alloc. // By default, everything starts off with read + write. fmt.Println(alloc.Access()) }
Output: read+write
func (*Allocation) Protect ¶
func (a *Allocation) Protect(access Access)
Protect protectes the allocation with the given access settings.
Example ¶
package main import ( "net" "unsafe" "github.com/prashantv/protectmem" ) func main() { ipAlloc := protectmem.Allocate(unsafe.Sizeof(net.IPAddr{})) ip := (*net.IPAddr)(ipAlloc.Ptr()) // Protect can be used to change the access permissions for the alloc. ipAlloc.Protect(protectmem.Read) // ip cannot be written to, any writes will crash. ip.Zone = "this will fail" }
Output:
func (*Allocation) Ptr ¶
func (a *Allocation) Ptr() unsafe.Pointer
Ptr returns an unsafe.Pointer that should be casted into the type that the user wants to use.
Example ¶
package main import ( "net" "unsafe" "github.com/prashantv/protectmem" ) func main() { ipAlloc := protectmem.Allocate(unsafe.Sizeof(net.IPAddr{})) // Ptr returns an unsafe.Pointer which can be casted into a pointer // of the type specified in Allocate. ip := (*net.IP)(ipAlloc.Ptr()) _, _ = ipAlloc, ip }
Output: