Memory Management

There are several important aspects to consider regarding memory management. Following the OWASP guidelines, the first step we must take to protect our application is the user input/output. Steps must be taken to ensure no malicious content is allowed. A more detailed overview of this aspect is in the Input Validation and the Output Encoding sections of this document.

Another important aspect regarding memory management is the buffer boundary checking. When dealing with functions that accept a number of bytes to copy, usually, in C-style languages, the size of the destination array must be checked to ensure we don't write past the allocated space. In Go, data types such as String are not NULL terminated, and in the case of String its header consists of the following information:

type StringHeader struct {
    Data uintptr
    Len  int
}

Despite this, boundary checks must be made (e.g. when looping). If we go beyond the set boundaries, Go will Panic.

A simple example:

func main() {
    strings := []string{"aaa", "bbb", "ccc", "ddd"}
    // Our loop is not checking the MAP length -> BAD
    for i := 0; i < 5; i++ {
        if len(strings[i]) > 0 {
            fmt.Println(strings[i])
        }
    }
}

Output:

aaa
bbb
ccc
ddd
panic: runtime error: index out of range

When our application uses resources, additional checks must also be made to ensure they have been closed and not rely solely on the Garbage Collector. This is applicable when dealing with connection objects, file handles, etc. In Go we can use Defer to perform these actions. Instructions in Defer are only executed when the surrounding functions finish execution.

defer func() {
    // Our cleanup code here
}

More information regarding Defer can be found in the Error Handling section of the document.

Usage of known vulnerable functions should also be avoided. In Go, the Unsafe package contains these functions. They should not be used in production environments, nor should the package itself. This also applies to the Testing package.

On the other hand, memory deallocation is handled by the garbage collector, which means that we don't have to worry about it. An interesting note is that it is possible to manually deallocate memory although it is not advised.

Quoting Golang's Github:

If you really want to manually manage memory with Go, implement your own memory allocator based on syscall.Mmap or cgo malloc/free.

Disabling GC for extended period of time is generally a bad solution for a concurrent language like Go. And Go's GC will only be better down the road.

results matching ""

    No results matching ""