mirror of
https://github.com/github/codeql.git
synced 2025-12-21 03:06:31 +01:00
301 lines
8.1 KiB
Go
301 lines
8.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
)
|
|
|
|
func main() {}
|
|
func good0() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret without overflowing to secret:
|
|
// NOTE: unsafe.Pointer(&harmless) == unsafe.Pointer(&harmless[0])
|
|
var data = (*[8]byte)(unsafe.Pointer(&harmless)) // OK
|
|
|
|
fmt.Println(string((*data)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func goodIndexExpr() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret without overflowing to secret:
|
|
// NOTE: unsafe.Pointer(&harmless) == unsafe.Pointer(&harmless[0])
|
|
var data = (*[8]byte)(unsafe.Pointer(&harmless[0])) // OK
|
|
|
|
fmt.Println(string((*data)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func goodIndexExprDifferentTypes() {
|
|
// A harmless piece of data:
|
|
harmless := [12]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret without overflowing to secret:
|
|
// Even tough `harmless` and `data` have types of different sizes,
|
|
// `data` is made of 8 bytes starting from `harmless[3]`,
|
|
// up until the end of `harmless` (from `harmless[3]` to
|
|
// the end of `harmless` is 8 bytes),
|
|
// which does not cross into `secret`.
|
|
var data = (*[8]byte)(unsafe.Pointer(&harmless[3])) // OK
|
|
|
|
fmt.Println(string((*data)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func badIndexExpr() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret.
|
|
// NOTE: unsafe.Pointer(&harmless) != unsafe.Pointer(&harmless[2])
|
|
// Even tough harmless and leaking have the same size,
|
|
// the new variable `leaking` will contain data starting from
|
|
// the address of the 3rd element of the `harmless` array,
|
|
// and continue for 8 bytes, going out of the boundaries of
|
|
// `harmless` and crossing into the memory occupied by `secret`.
|
|
var leaking = (*[8]byte)(unsafe.Pointer(&harmless[2])) // BAD
|
|
|
|
fmt.Println(string((*leaking)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func good2() {
|
|
// A harmless piece of data:
|
|
harmless := uint(123)
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret:
|
|
var data = (*int)(unsafe.Pointer(&harmless)) // TODO: is this really OK?
|
|
|
|
fmt.Println(*data)
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
|
|
func bad0() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we get the pointer to the first byte of harmless)
|
|
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless[0])) // BAD
|
|
|
|
fmt.Println(string((*leaking)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
|
|
func bad1() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless)
|
|
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(string((*leaking)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
|
|
type Harmless [8]byte
|
|
|
|
func bad2() {
|
|
// A harmless piece of data:
|
|
harmless := Harmless{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless)
|
|
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(string((*leaking)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad3() {
|
|
// A harmless piece of data:
|
|
harmless := [8]string{"A", "A", "A", "A", "A", "A", "A", "A"}
|
|
// Something secret:
|
|
secret := [9]string{"s", "e", "n", "s", "i", "t", "i", "v", "e"}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless)
|
|
var leaking = (*[8 + 9]string)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(*leaking)
|
|
fmt.Println([17]string((*leaking)))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == "42" {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad4() {
|
|
type harmlessType struct {
|
|
Data [8]byte
|
|
}
|
|
// A harmless piece of data:
|
|
harmless := harmlessType{
|
|
Data: [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'},
|
|
}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless)
|
|
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(string((*leaking)[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad5() {
|
|
type harmlessType struct {
|
|
Data [8]byte
|
|
}
|
|
// A harmless piece of data:
|
|
harmless := harmlessType{
|
|
Data: [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'},
|
|
}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless)
|
|
var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless.Data)) // BAD
|
|
|
|
fmt.Println(string(leaking[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad6() {
|
|
// A harmless piece of data:
|
|
harmless := [8]byte{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret:
|
|
var leaking = buffer_request(unsafe.Pointer(&harmless)) // BAD (see inside buffer_request func)
|
|
|
|
fmt.Println((string)(leaking[:]))
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func buffer_request(req unsafe.Pointer) [8 + 9]byte {
|
|
// The length of req is 8 bytes,
|
|
// but we cast it to a longer array,
|
|
// which means that when the resulting array
|
|
// will be read, the read will also contain pieces of
|
|
// data from `secret`.
|
|
var buf [8 + 9]byte
|
|
buf = *(*[8 + 9]byte)(req) // BAD (from above func)
|
|
return buf
|
|
}
|
|
func bad7() {
|
|
// A harmless piece of data:
|
|
harmless := [1]int64{23}
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless);
|
|
// the leaking array will not contain letters,
|
|
// but integers representing bytes from `secret`.
|
|
var leaking = (*[4]int64)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(*leaking)
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad8() {
|
|
// A harmless piece of data:
|
|
harmless := int8(123)
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless);
|
|
// the leaking data will contain some bits from `secret`.
|
|
var leaking = (*int64)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(*leaking)
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|
|
func bad9() {
|
|
// A harmless piece of data:
|
|
harmless := int8(123)
|
|
// Something secret:
|
|
secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'}
|
|
|
|
// Read before secret, overflowing into secret
|
|
// (notice we read more than the length of harmless);
|
|
// the leaking data will contain some bits from `secret`.
|
|
var leaking = (*int)(unsafe.Pointer(&harmless)) // BAD
|
|
|
|
fmt.Println(*leaking)
|
|
|
|
// Avoid optimization:
|
|
if secret[0] == 123 {
|
|
fmt.Println("hello world")
|
|
}
|
|
}
|