[teamai] Push 87 resource(s) from XingfenD
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
# Memory Safety Security Rules
|
||||
|
||||
Memory safety vulnerabilities can lead to crashes, data corruption, and security compromises.
|
||||
|
||||
**Rules:**
|
||||
|
||||
1. Integer overflow MUST be checked at boundaries — NEVER trust unchecked arithmetic on external input.
|
||||
2. `unsafe` MUST NOT be used in application code — restrict to low-level libraries with thorough review.
|
||||
3. Data races MUST be detected with `-race` flag in CI.
|
||||
|
||||
---
|
||||
|
||||
## Integer Overflow — High
|
||||
|
||||
Integer overflows can cause unexpected behavior and crashes.
|
||||
|
||||
**Bad:**
|
||||
|
||||
```go
|
||||
func allocateBuffer(rows, cols int) []byte {
|
||||
size := rows * cols // DON'T: Can overflow
|
||||
return make([]byte, size)
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```go
|
||||
import "math"
|
||||
|
||||
func safeMultiply(a, b int) (int, error) {
|
||||
if a == 0 || b == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if a > math.MaxInt/b {
|
||||
return 0, errors.New("integer overflow")
|
||||
}
|
||||
result := a * b
|
||||
if result/b != a {
|
||||
return 0, errors.New("overflow detected")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func allocateBuffer(rows, cols int) ([]byte, error) {
|
||||
size, err := safeMultiply(rows, cols)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
const maxBufferSize = 100 * 1024 * 1024 // 100MB limit
|
||||
if size > maxBufferSize {
|
||||
return nil, errors.New("buffer size exceeds limit")
|
||||
}
|
||||
return make([]byte, size), nil
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## math/big.Rat Issues — Low
|
||||
|
||||
Rat can consume large amounts of memory if denominators grow without bounds.
|
||||
|
||||
**Bad:**
|
||||
|
||||
```go
|
||||
import "math/big"
|
||||
|
||||
func unsafeFraction(operations int) *big.Rat {
|
||||
r := big.NewRat(1, 1)
|
||||
for i := 0; i < operations; i++ {
|
||||
r.Mul(r, big.NewRat(int64(i+1), int64(i+2))) // DON'T
|
||||
}
|
||||
return r // Could be memory intensive
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```go
|
||||
const maxRatNumBits = 1000
|
||||
|
||||
func safeFraction(operations int) (*big.Rat, error) {
|
||||
r := big.NewRat(1, 1)
|
||||
for i := 0; i < operations; i++ {
|
||||
r.Mul(r, big.NewRat(int64(i+1), int64(i+2)))
|
||||
if r.Num().BitLen() > maxRatNumBits || r.Denom().BitLen() > maxRatNumBits {
|
||||
return nil, errors.New("fraction precision too large")
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Memory Aliasing Vulnerability — Medium
|
||||
|
||||
Memory aliasing can cause data corruption and race conditions.
|
||||
|
||||
**Bad:**
|
||||
|
||||
```go
|
||||
func reverseBytes(data []byte) {
|
||||
for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
|
||||
data[i], data[j] = data[j], data[i] // DON'T if slices alias
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```go
|
||||
import "unsafe"
|
||||
|
||||
func checkOverlap(a, b []byte) bool {
|
||||
if len(a) == 0 || len(b) == 0 {
|
||||
return false
|
||||
}
|
||||
aStart := uintptr(unsafe.Pointer(&a[0]))
|
||||
aEnd := aStart + uintptr(len(a))
|
||||
bStart := uintptr(unsafe.Pointer(&b[0]))
|
||||
bEnd := bStart + uintptr(len(b))
|
||||
return aStart < bEnd && bStart < aEnd
|
||||
}
|
||||
|
||||
func safeCopy(dest, src []byte) {
|
||||
if checkOverlap(dest, src) {
|
||||
temp := make([]byte, len(src))
|
||||
copy(temp, src)
|
||||
copy(dest, temp)
|
||||
} else {
|
||||
copy(dest, src)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Use of unsafe Package — High
|
||||
|
||||
The unsafe package bypasses Go's type safety and memory safety.
|
||||
|
||||
**Bad:**
|
||||
|
||||
```go
|
||||
import "unsafe"
|
||||
|
||||
func UnsafeStringToBytes(s string) []byte {
|
||||
return (*[0x7fffffff]byte)(unsafe.Pointer(
|
||||
(*reflect.StringHeader)(unsafe.Pointer(&s)).Data,
|
||||
))[:len(s):len(s)] // DON'T: memory corruption risk
|
||||
}
|
||||
|
||||
func TypePun(value uint64) float64 {
|
||||
return *(*float64)(unsafe.Pointer(&value)) // DON'T
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```go
|
||||
// Safe string encoding
|
||||
func StringToBytes(s string) []byte {
|
||||
return []byte(s)
|
||||
}
|
||||
func BytesToString(b []byte) string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Safe type conversion
|
||||
import "encoding/binary"
|
||||
func Uint64ToFloat64(value uint64) float64 {
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, value)
|
||||
bits := binary.LittleEndian.Uint64(buf)
|
||||
return math.Float64frombits(bits)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Races — High
|
||||
|
||||
Go's race detector is your primary defense.
|
||||
|
||||
**Bad:**
|
||||
|
||||
```go
|
||||
type Counter struct {
|
||||
value int
|
||||
}
|
||||
|
||||
func (c *Counter) Increment() {
|
||||
c.value++ // DON'T: Data race without sync
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
|
||||
```go
|
||||
import "sync"
|
||||
|
||||
type Counter struct {
|
||||
value int
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (c *Counter) Increment() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.value++
|
||||
}
|
||||
|
||||
// Or atomic for simple cases
|
||||
import "sync/atomic"
|
||||
type AtomicCounter struct {
|
||||
value int64
|
||||
}
|
||||
func (c *AtomicCounter) Increment() {
|
||||
atomic.AddInt64(&c.value, 1)
|
||||
}
|
||||
```
|
||||
|
||||
## Always Run Race Detector
|
||||
|
||||
```bash
|
||||
go test -race ./...
|
||||
go build -race
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CWE References
|
||||
|
||||
- **CWE-190**: Integer Overflow or Wraparound
|
||||
- **CWE-119**: Improper Restriction of Operations within Bounds
|
||||
- **CWE-125**: Out-of-bounds Read
|
||||
- **CWE-787**: Out-of-bounds Write
|
||||
- **CWE-362**: Race Condition
|
||||
- **CWE-367**: Time-of-check Time-of-use (TOCTOU)
|
||||
Reference in New Issue
Block a user