Add tests

This commit is contained in:
Slavomir
2020-06-30 11:31:24 +03:00
parent c71ecd678e
commit 8473ed0d81
4 changed files with 339 additions and 0 deletions

View File

@@ -1,5 +1,13 @@
/**
* @name Wrong usage of package unsafe
* @description Casting between variables with different memory sizes can produce reads to
* memory locations that are after the target buffer, and/or unexpected values.
* @kind path-problem
* @problem.severity error
* @id go/wrong-usage-of-unsafe
* @tags security
* external/cwe/cwe-119
* external/cwe/cwe-126
*/
import go

View File

@@ -0,0 +1,90 @@
edges
| WrongUsageOfUnsafe.go:17:27:17:51 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:17:16:17:52 | type conversion |
| WrongUsageOfUnsafe.go:17:27:17:51 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:17:16:17:52 | type conversion |
| WrongUsageOfUnsafe.go:33:23:33:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:33:16:33:48 | type conversion |
| WrongUsageOfUnsafe.go:33:23:33:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:33:16:33:48 | type conversion |
| WrongUsageOfUnsafe.go:51:31:51:58 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:51:16:51:59 | type conversion |
| WrongUsageOfUnsafe.go:51:31:51:58 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:51:16:51:59 | type conversion |
| WrongUsageOfUnsafe.go:69:31:69:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:69:16:69:56 | type conversion |
| WrongUsageOfUnsafe.go:69:31:69:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:69:16:69:56 | type conversion |
| WrongUsageOfUnsafe.go:89:31:89:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:89:16:89:56 | type conversion |
| WrongUsageOfUnsafe.go:89:31:89:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:89:16:89:56 | type conversion |
| WrongUsageOfUnsafe.go:106:33:106:57 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:106:16:106:58 | type conversion |
| WrongUsageOfUnsafe.go:106:33:106:57 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:106:16:106:58 | type conversion |
| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion |
| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion |
| WrongUsageOfUnsafe.go:151:31:151:60 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:151:16:151:61 | type conversion |
| WrongUsageOfUnsafe.go:151:31:151:60 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:151:16:151:61 | type conversion |
| WrongUsageOfUnsafe.go:167:31:167:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer |
| WrongUsageOfUnsafe.go:167:31:167:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer |
| WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer | WrongUsageOfUnsafe.go:183:9:183:27 | type conversion |
| WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer | WrongUsageOfUnsafe.go:183:9:183:27 | type conversion |
| WrongUsageOfUnsafe.go:196:28:196:52 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:196:16:196:53 | type conversion |
| WrongUsageOfUnsafe.go:196:28:196:52 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:196:16:196:53 | type conversion |
| WrongUsageOfUnsafe.go:214:25:214:49 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:214:16:214:50 | type conversion |
| WrongUsageOfUnsafe.go:214:25:214:49 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:214:16:214:50 | type conversion |
| WrongUsageOfUnsafe.go:232:23:232:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:232:16:232:48 | type conversion |
| WrongUsageOfUnsafe.go:232:23:232:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:232:16:232:48 | type conversion |
nodes
| WrongUsageOfUnsafe.go:17:16:17:52 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:17:16:17:52 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:17:27:17:51 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:17:27:17:51 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:33:16:33:48 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:33:16:33:48 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:33:23:33:47 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:33:23:33:47 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:51:16:51:59 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:51:16:51:59 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:51:31:51:58 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:51:31:51:58 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:69:16:69:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:69:16:69:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:69:31:69:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:69:31:69:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:89:16:89:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:89:16:89:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:89:31:89:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:89:31:89:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:106:16:106:58 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:106:16:106:58 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:106:33:106:57 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:106:33:106:57 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:151:16:151:61 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:151:16:151:61 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:151:31:151:60 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:151:31:151:60 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:167:31:167:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:167:31:167:55 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer | semmle.label | definition of req : unsafe.Pointer |
| WrongUsageOfUnsafe.go:176:21:176:23 | definition of req : unsafe.Pointer | semmle.label | definition of req : unsafe.Pointer |
| WrongUsageOfUnsafe.go:183:9:183:27 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:183:9:183:27 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:196:16:196:53 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:196:16:196:53 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:196:28:196:52 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:196:28:196:52 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:214:16:214:50 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:214:16:214:50 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:214:25:214:49 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:214:25:214:49 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:232:16:232:48 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:232:16:232:48 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:232:23:232:47 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
| WrongUsageOfUnsafe.go:232:23:232:47 | type conversion : unsafe.Pointer | semmle.label | type conversion : unsafe.Pointer |
#select
| WrongUsageOfUnsafe.go:51:16:51:59 | type conversion | WrongUsageOfUnsafe.go:51:31:51:58 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:51:16:51:59 | type conversion | $@. | WrongUsageOfUnsafe.go:51:31:51:58 | type conversion | Dangerous type up-casting to [17]uint8 from uint8 |
| WrongUsageOfUnsafe.go:69:16:69:56 | type conversion | WrongUsageOfUnsafe.go:69:31:69:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:69:16:69:56 | type conversion | $@. | WrongUsageOfUnsafe.go:69:31:69:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
| WrongUsageOfUnsafe.go:89:16:89:56 | type conversion | WrongUsageOfUnsafe.go:89:31:89:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:89:16:89:56 | type conversion | $@. | WrongUsageOfUnsafe.go:89:31:89:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
| WrongUsageOfUnsafe.go:106:16:106:58 | type conversion | WrongUsageOfUnsafe.go:106:33:106:57 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:106:16:106:58 | type conversion | $@. | WrongUsageOfUnsafe.go:106:33:106:57 | type conversion | Dangerous array type casting to [17]string from [8]string |
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous type up-casting to [17]uint8 from harmlessType |
| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type |
| WrongUsageOfUnsafe.go:151:16:151:61 | type conversion | WrongUsageOfUnsafe.go:151:31:151:60 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:151:16:151:61 | type conversion | $@. | WrongUsageOfUnsafe.go:151:31:151:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
| WrongUsageOfUnsafe.go:183:9:183:27 | type conversion | WrongUsageOfUnsafe.go:167:31:167:55 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:183:9:183:27 | type conversion | $@. | WrongUsageOfUnsafe.go:167:31:167:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 |
| WrongUsageOfUnsafe.go:196:16:196:53 | type conversion | WrongUsageOfUnsafe.go:196:28:196:52 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:196:16:196:53 | type conversion | $@. | WrongUsageOfUnsafe.go:196:28:196:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 |
| WrongUsageOfUnsafe.go:214:16:214:50 | type conversion | WrongUsageOfUnsafe.go:214:25:214:49 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:214:16:214:50 | type conversion | $@. | WrongUsageOfUnsafe.go:214:25:214:49 | type conversion | Dangerous numeric type casting to int64 from int8 |
| WrongUsageOfUnsafe.go:232:16:232:48 | type conversion | WrongUsageOfUnsafe.go:232:23:232:47 | type conversion : unsafe.Pointer | WrongUsageOfUnsafe.go:232:16:232:48 | type conversion | $@. | WrongUsageOfUnsafe.go:232:23:232:47 | type conversion | Dangerous numeric type casting to int from int8 |

View File

@@ -0,0 +1,240 @@
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:
var leaking = (*[8]byte)(unsafe.Pointer(&harmless)) // OK
fmt.Println(string((*leaking)[:]))
// Avoid optimization:
if secret[0] == 123 {
fmt.Println("hello world")
}
}
func good1() {
// 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 leaking = (*int)(unsafe.Pointer(&harmless)) // TODO: is this really OK?
fmt.Println(*leaking)
// Avoid optimization:
if secret[0] == 123 {
fmt.Println("hello world")
}
}
func bad00() {
// 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 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 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 bad1() {
// 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 bad2() {
// 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 bad3() {
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 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.Data)) // BAD
fmt.Println(string(leaking[:]))
// Avoid optimization:
if secret[0] == 123 {
fmt.Println("hello world")
}
}
func bad5() {
// 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)
return buf
}
func bad6() {
// 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 bad7() {
// 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 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 = (*int)(unsafe.Pointer(&harmless)) // BAD
fmt.Println(*leaking)
// Avoid optimization:
if secret[0] == 123 {
fmt.Println("hello world")
}
}

View File

@@ -0,0 +1 @@
experimental/Unsafe/WrongUsageOfUnsafe.ql