fts_open is defined like this:
fts_open()
The fts_open() function takes a pointer to an array of character
pointers naming one or more paths which make up a logical file
hierarchy to be traversed.  The array must be terminated by a
null pointer.
C does not have direct support for arrays; it only has pointers.
In your case you pass fts_open a single valid pointer but it is not located in an array which has a NULL pointer as the immediately following element, so fts_open continues to scan the memory past &path — looking for a NULL pointer, — and eventually tries to read memory at some address it is forbidden to do so (usually because the page at that address was not allocated).
A way to fix it is to create that array and initialize it on the C side.
Looks like you're using a reasonably up-to-date standard of C, so let's just use direct literal to initialize the array:
package main
/*
#include <stddef.h> // for NULL
#include <stdint.h>
#include <stdlib.h> // for C.free
#include <fts.h>
#include <sys/stat.h>
uintmax_t get_total_size(char *path)
{
    uintmax_t total_size = 0;
    char * path_argv[2] = {path, NULL};
    FTS *fts = fts_open(path_argv, FTS_PHYSICAL, NULL);
    FTSENT *fent;
    while ((fent = fts_read(fts)) != NULL)
        if (fent->fts_info == FTS_F)
            total_size += fent->fts_statp->st_size;
    fts_close(fts);
    return total_size;
}
*/
import "C"
import (
    "fmt"
    "unsafe"
)
func main() {
    cpath := C.CString("/usr")
    defer C.free(unsafe.Pointer(cpath))
    fmt.Println(C.get_total_size(cpath))
}
Note that your program has one bug and one possible problem:
- A bug is that the call 
C.CString allocates a chunk of memory by performing a call to malloc(3) from the linked C library, and you did not free that memory block. 
- The symbol 
NULL is defined in "stddef.h"; you might or might not get an error when compiling. 
I've fixed both problems in my example.
A further improvement over our example might be leveraging the ability of fts_* functions to scan multiple paths in a single run; if we were to implement that, it would have more sense to allocate the array for the 1st argument of fts_open on the Go's side:
package main
/*
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <fts.h>
#include <sys/stat.h>
uintmax_t get_total_size(char * const *path_argv)
{
    uintmax_t total_size = 0;
    FTS *fts = fts_open(path_argv, FTS_PHYSICAL, NULL);
    FTSENT *fent;
    while ((fent = fts_read(fts)) != NULL)
        if (fent->fts_info == FTS_F)
            total_size += fent->fts_statp->st_size;
    fts_close(fts);
    return total_size;
}
*/
import "C"
import (
    "fmt"
    "unsafe"
)
func main() {
    fmt.Println(getTotalSize("/usr", "/etc"))
}
func getTotalSize(paths ...string) uint64 {
    argv := make([]*C.char, len(paths)+1)
    for i, path := range paths {
        argv[i] = C.CString(path)
        defer C.free(unsafe.Pointer(argv[i]))
    }
    return uint64(C.get_total_size(&argv[0]))
}
Note that here we did not explicitly zero out the last argument of argv because — contrary to C, — Go initializes each allocated memory block with zeroes, so once argv is allocated, all its memory is already zeroed.