ERROR: AddressSanitizer failed to deallocate - memory-management

I am fuzzing using a harness.
Get this error in my fuzzer
==1303173==ERROR: AddressSanitizer failed to deallocate 0x43000 (274432) bytes at address 0x7ffb83969000
==1303173==AddressSanitizer CHECK failed: /build/llvm-toolchain-9-uSl4bC/llvm-toolchain-9-9/projects/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc:61 "(("unable to unmap" && 0)) != (0)" (0x0, 0x0)
==1303173==ERROR: AddressSanitizer failed to deallocate 0xcf000 (847872) bytes at address 0x7ffb80300000
==1303173==AddressSanitizer CHECK failed: /build/llvm-toolchain-9-uSl4bC/llvm-toolchain-9-9/projects/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc:61 "(("unable to unmap" && 0)) != (0)" (0x0, 0x0)
Any idea why it can happen each time after ca. 12 hours of fuzzing? What could be the reasons? It is deallocation, should be not relevant, but free mem seems to be also there.
Thanks,

Related

Why a byte buffer from CGO can reads correctly but write fault?

I am using this library https://github.com/billziss-gh/cgofuse, and some interfaces need to be implemented,one of them looks like this:
func (self *Memfs) Write(path string, buff []byte, ofst int64, fh uint64) (n int) {
defer trace(path, buff, ofst, fh)(&n)
defer self.synchronize()()
node := self.getNode(path, fh)
if nil == node {
return -fuse.ENOENT
}
endofst := ofst + int64(len(buff))
if endofst > node.stat.Size {
node.data = resize(node.data, endofst, true)
node.stat.Size = endofst
}
fmt.Println("len(buff) = ", len(buff)) // (1)
fmt.Println("cap(buff) = ", cap(buff)) // (2)
fmt.Println("buff[0] = ", buff[0]) // (3)
buff[0] = 1 // (4)
n = copy(node.data[ofst:endofst], buff)
tmsp := fuse.Now()
node.stat.Ctim = tmsp
node.stat.Mtim = tmsp
return
}
This is a file system, Write is called when writing to a file. I added (1), (2), (3), (4) in the above code, but it was wrong at (4). The error stack is as follows:
unexpected fault address 0x116e6c60390
fatal error: fault
[signal 0xc0000005 code=0x1 addr=0x116e6c60390 pc=0xca7dad]
goroutine 17 [running, locked to thread]:
runtime.throw(0xcf373f, 0x5)
D:/Scoop/apps/go/current/src/runtime/panic.go:1117 +0x79 fp=0xc000033bc8 sp=0xc000033b98 pc=0xc18db9
runtime.sigpanic()
D:/Scoop/apps/go/current/src/runtime/signal_windows.go:245 +0x2d6 fp=0xc000033c20 sp=0xc000033bc8 pc=0xc2b7d6
main.(*Memfs).Write(0xc00001e400, 0xc00000a2b0, 0x9, 0x116e6c60390, 0x40000, 0x40000000, 0x0, 0x2, 0x9)
D:/code/go/LiangFs/tool/memfs.go:310 +0x4cd fp=0xc000033de0 sp=0xc000033c20 pc=0xca7dad
github.com/billziss-gh/cgofuse/fuse.hostWrite(0x116e00d1480, 0x116e6c60390, 0x40000, 0x0, 0x1518fff7c8, 0x0)
D:/go/pkg/mod/github.com/billziss-gh/cgofuse#v1.5.0/fuse/host.go:255 +0x102 fp=0xc000033e60 sp=0xc000033de0 pc=0xc9c282
github.com/billziss-gh/cgofuse/fuse.go_hostWrite(...)
D:/go/pkg/mod/github.com/billziss-gh/cgofuse#v1.5.0/fuse/host_cgo.go:911
_cgoexp_12ef5be0dd8c_go_hostWrite(0x1518fff710)
_cgo_gotypes.go:738 +0x59 fp=0xc000033ea0 sp=0xc000033e60 pc=0xca2919
runtime.cgocallbackg1(0xca28c0, 0x1518fff710, 0x0)
D:/Scoop/apps/go/current/src/runtime/cgocall.go:292 +0x19a fp=0xc000033f40 sp=0xc000033ea0 pc=0xbe4c5a
runtime.cgocallbackg(0xca28c0, 0x1518fff710, 0x0)
D:/Scoop/apps/go/current/src/runtime/cgocall.go:228 +0xfc fp=0xc000033fb8 sp=0xc000033f40 pc=0xbe49bc
runtime.cgocallback(0x0, 0x0, 0x0)
D:/Scoop/apps/go/current/src/runtime/asm_amd64.s:788 +0xc0 fp=0xc000033fe0 sp=0xc000033fb8 pc=0xc48bc0
runtime.goexit()
D:/Scoop/apps/go/current/src/runtime/asm_amd64.s:1371 +0x1 fp=0xc000033fe8 sp=0xc000033fe0 pc=0xc48ea1
goroutine 1 [syscall]:
github.com/billziss-gh/cgofuse/fuse._Cfunc_hostMount(0x3, 0xc00001e420, 0x116e0316540, 0x0)
_cgo_gotypes.go:502 +0x4f
github.com/billziss-gh/cgofuse/fuse.c_hostMount.func1(0xc000000003, 0xc00001e420, 0x116e0316540, 0x116e0316540)
D:/go/pkg/mod/github.com/billziss-gh/cgofuse#v1.5.0/fuse/host_cgo.go:820 +0x8c
github.com/billziss-gh/cgofuse/fuse.c_hostMount(0xc000000003, 0xc00001e420, 0x116e0316540, 0xb)
D:/go/pkg/mod/github.com/billziss-gh/cgofuse#v1.5.0/fuse/host_cgo.go:820 +0x45
github.com/billziss-gh/cgofuse/fuse.(*FileSystemHost).Mount(0xc00003e040, 0xcf4632, 0xb, 0xc000034210, 0x0, 0x0, 0x1ffffff00)
D:/go/pkg/mod/github.com/billziss-gh/cgofuse#v1.5.0/fuse/host.go:704 +0x413
main.main()
D:/code/go/LiangFs/tool/memfs.go:594 +0xce
len(buff) = 262144
cap(buff) = 1073741824
buff[0] = 97
the content of buff is all 97, becasue I copy the following file to this file system:
The code comes from the example in the library https://github.com/billziss-gh/cgofuse/blob/master/examples/memfs/memfs.go , I just added the (1), (2), (3), (4) mentioned above.
My os is windows 10, go version is go1.16.7 windows/amd64.
Why does assigning a slice element make a mistake? Is it because the library uses CGO?
I am the author of both WinFsp and cgofuse and can explain what is happening here.
The buffer that you receive in Write should always be treated as a read-only buffer. Attempting to write into this buffer may result in an access violation. This is by design.
When an application issues a WriteFile request, the WinFsp kernel mode driver has to somehow transfer the data from the application to the user mode file system. The driver has a few different strategies for doing so and under certain circumstances it will choose a zero-copy technique: it will map the application buffer directly into the address space of the user mode file system, thus avoiding an expensive memory copy.
In the case of Write this zero-copy mapping will always be read-only in order to avoid the case where a user mode accidentally or maliciously writes into an application's WriteFile buffer. (Also note that when the WinFsp driver sets up this mapping, it does so in a way that ensures that there is no accidental data leakage from the application into the user mode file system either.)
Since nothing is printed after buf[0] = 1 // (4), we don't know wether the panic comes from this line of code or a line afterwards ; you have to debug further to spot where the bug lies.
Actually : the stack trace you pasted mentions LiangFs/tool/memfs.go:310.
If this line number refers to the file you linked to, this line is the return instruction in your .Write() function.
The error must be triggered by one of the two defer calls (which get executed when you return from your function).

GetProcessIoCounters errors out with code 998 [duplicate]

This question already has answers here:
Error 998 (Invalid access to memory location) for when calling GetPointerFrameTouchInfo [duplicate]
(1 answer)
WriteConsole access violation in function call but not from main()
(2 answers)
VirtualProtectEx fails with ERROR_NOACCESS (error code 998)
(1 answer)
Invalid access to memory location with ReadFile
(2 answers)
Closed 2 years ago.
I am trying to get the PIO_COUNTERS for the current process by doing:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
PIO_COUNTERS ctr = nullptr;
if (!GetProcessIoCounters(handle, ctr)) {
DWORD dw = GetLastError();
}
I get value of dw as 998 which is "Invalid access of the memory location". This essentially means that the handle I am using does not have enough privileges, but this is the flag with the max access control privileges. I also tried using the handle given by "GetCurrentProcess" (which is different from the one I got above) but that also gave error code 998 after passing it to GetProcessIoCounters.
Can somebody please help me out here?
Thanks in advance.
The 'invalid access' error is occurring because you are passing a nullptr value for the address of the IO_COUNTERS structure into which to write the information you are retrieving. You need to give the address of an actual structure for this:
DWORD pid = GetCurrentProcessId();
auto handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
IO_COUNTERS info;
if (!GetProcessIoCounters(handle, &info)) { // Pass the address of your structure!
DWORD dw = GetLastError();
}
You can then access the various members of the info structure to get the information you want.

Why does go v1.8 fail to allocate heap bitmap on armv7 when importing zmq4?

I'm using go v1.8 on an armv7 target and everything works until I import zeromq, and then not even this works:
package main
import (
zmq "github.com/pebbe/zmq4"
"fmt"
)
func main() {
fmt.Println(zmq.Version())
}
Running it on the target gives the following:
./zmq
fatal error: runtime: out of memory
runtime stack:
runtime.throw(0xc8d3d, 0x16)
/usr/lib/go/src/runtime/panic.go:596 +0x70 fp=0x7eb018a0 sp=0x7eb01894
runtime.sysMap(0x6d752000, 0x74d4000, 0x1, 0x146b60)
/usr/lib/go/src/runtime/mem_linux.go:227 +0xb0 fp=0x7eb018c4 sp=0x7eb018a0
runtime.(*mheap).mapBits(0x139d58, 0x74d26000)
/usr/lib/go/src/runtime/mbitmap.go:159 +0x94 fp=0x7eb018dc sp=0x7eb018c4
runtime.(*mheap).sysAlloc(0x139d58, 0x100000, 0x30414)
/usr/lib/go/src/runtime/malloc.go:428 +0x2dc fp=0x7eb0191c sp=0x7eb018dc
runtime.(*mheap).grow(0x139d58, 0x8, 0x0)
/usr/lib/go/src/runtime/mheap.go:774 +0xd0 fp=0x7eb0194c sp=0x7eb0191c
runtime.(*mheap).allocSpanLocked(0x139d58, 0x1, 0x0)
/usr/lib/go/src/runtime/mheap.go:678 +0x468 fp=0x7eb0196c sp=0x7eb0194c
runtime.(*mheap).alloc_m(0x139d58, 0x1, 0x10, 0x0, 0x0)
/usr/lib/go/src/runtime/mheap.go:562 +0xdc fp=0x7eb019a4 sp=0x7eb0196c
runtime.(*mheap).alloc.func1()
/usr/lib/go/src/runtime/mheap.go:627 +0x3c fp=0x7eb019c0 sp=0x7eb019a4
runtime.systemstack(0x7eb019d4)
/usr/lib/go/src/runtime/asm_arm.s:278 +0xa8 fp=0x7eb019c4 sp=0x7eb019c0
runtime.(*mheap).alloc(0x139d58, 0x1, 0x10, 0x100, 0x1)
/usr/lib/go/src/runtime/mheap.go:628 +0x60 fp=0x7eb019ec sp=0x7eb019c4
runtime.(*mcentral).grow(0x13ab98, 0x0)
/usr/lib/go/src/runtime/mcentral.go:212 +0x84 fp=0x7eb01a18 sp=0x7eb019ec
runtime.(*mcentral).cacheSpan(0x13ab98, 0x146b68)
/usr/lib/go/src/runtime/mcentral.go:93 +0x104 fp=0x7eb01a5c sp=0x7eb01a18
runtime.(*mcache).refill(0x649e5000, 0x10, 0x146b68)
/usr/lib/go/src/runtime/mcache.go:122 +0x7c fp=0x7eb01a70 sp=0x7eb01a5c
runtime.(*mcache).nextFree.func1()
/usr/lib/go/src/runtime/malloc.go:525 +0x24 fp=0x7eb01a80 sp=0x7eb01a70
runtime.systemstack(0x7eb01aa4)
/usr/lib/go/src/runtime/asm_arm.s:278 +0xa8 fp=0x7eb01a84 sp=0x7eb01a80
runtime.(*mcache).nextFree(0x649e5000, 0x649e5010, 0x7eb01acc, 0x1ebd4, 0x21c40)
/usr/lib/go/src/runtime/malloc.go:526 +0x9c fp=0x7eb01ab0 sp=0x7eb01a84
runtime.mallocgc(0xf0, 0xc2548, 0x1, 0x64a26001)
/usr/lib/go/src/runtime/malloc.go:678 +0x8c0 fp=0x7eb01b08 sp=0x7eb01ab0
runtime.newobject(0xc2548, 0x1384a0)
/usr/lib/go/src/runtime/malloc.go:807 +0x2c fp=0x7eb01b1c sp=0x7eb01b08
runtime.malg(0x8000, 0x2710)
/usr/lib/go/src/runtime/proc.go:2821 +0x1c fp=0x7eb01b38 sp=0x7eb01b1c
runtime.mpreinit(0x138730)
/usr/lib/go/src/runtime/os_linux.go:302 +0x1c fp=0x7eb01b44 sp=0x7eb01b38
runtime.mcommoninit(0x138730)
/usr/lib/go/src/runtime/proc.go:540 +0x94 fp=0x7eb01b5c sp=0x7eb01b44
runtime.schedinit()
/usr/lib/go/src/runtime/proc.go:476 +0x40 fp=0x7eb01b78 sp=0x7eb01b5c
runtime.rt0_go(0x7eb01d14, 0x76ee4000, 0x7eb01d14, 0x1, 0x5cd10, 0x7eb01c58, 0x76f8e000, 0xcef6f281, 0xc6a63e08, 0x128, ...)
/usr/lib/go/src/runtime/asm_arm.s:61 +0x84 fp=0x7eb01bb8 sp=0x7eb01b78
Tracing shows the offending mmap:
mmap2(0x74c54000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x74c54000
mmap2(0x6d77e000, 122511360, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
The first one is right, that's the chunk size, but the second is where it allocates the bitmap. It should be probably 16x smaller.
I tried debugging but it works under GDB. Maybe GDB does some virtualization?
gdbserver :1000 zmq
Process zmq created; pid = 817
Listening on port 1000
Remote debugging from host 10.0.0.36
4 2 1
Child exited with status 0
So far, all pure go programs I've tested work as well.
Why does importing zeromq cause it to fail? Is there a bug in the arm port of go?
Fixed by https://github.com/golang/go/commit/bb6309cd63b35a81a8527efaad58847a83039947
libzmq must contain some global constructors which adjust the process memory map before the go runtime starts.

Read a large amount of data from network file fails in virtual machine

I want to read a network file in a Windows Server 2003 VM over VMWare ESX. This simple code fails (in Visual Studio 2010)
hFile = CreateFileA("\\MyServer\myfile",
GENERIC_READ, // open for writing
FILE_SHARE_READ, // do not share
NULL, // default security
OPEN_EXISTING, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE) return;
char * buffer = (char*)malloc(bufferSize);
if ( buffer == NULL) return;
if( FALSE == ReadFile(hFile, buffer, bufferSize, &dwBytesToRead, NULL) )
{
printf("Terminal failure: Unable to read from file, code is %d.\n", GetLastError());
CloseHandle(hFile);
return;
}
When bufferSize is greater than 40,000,000, ReadFile fails and GetLastError return 1450 which means "Insufficient system resources exist to complete the requested service. "
Some additional information:
1) This code works in a physical machine
2) My VM has 4 cores and 16 GB memory, and I change page file size between 8G and 24G, no effect, still fail.
3) \\MyServer\myfile is actually in the local machine where the code is running. However if I change the file to d:\myfile (the same file as \\MyServer\myfile), then ReadFile succeeds
4) The code works when bufferSize is less than 30,000,000
It looks like VMWare ESC put some restrictions on Windows. Can someone give me suggestion on how to debug/fix it? (without lower bufferSize)
Thanks a lot!
Try first with your ideal buffer size, then if you get error 1450, reduce the buffer size and try again.
Extremely large buffer sizes are not going to help performance particularly over a network.

Is my loop wrong ? Do I misuse ReadFile() and I/O completion port ?

I want to implement a server/client using named pipes (for IPC).I'm using async (overlapped) connections and I/O completion port (I searched a lot and it seems that it is the most efficient way to do that).
First here are the codes:
server: http://pastebin.com/XxeXdunC
and client: http://pastebin.com/fbCH2By8
The problem is in the server (i can improve the client but i will do that when the server works).
I use I/O completion port like that : basically, I run a thread in which I call ReadFile(). If it returns TRUE, I get all the data, if it returns FALSE, and the error is ERROR_IO_PENDING, I wait with GetQueuedCompletionStatus().
What is strange is that, even if I read all the data, the last ReadFile() call fails and the error is ERROR_IO_PENDING
The thread in which I call ReadFile() is beginning line 64 of the server code.
The client sends 24 bytes (the string "salut, c'est le client !") and the ReadFile() buffer is of length 5 bytes (to check how my server deals data that is larger than the Readfile() buffer)
The output is:
waiting for client...
WaitForMultipleObjects : 0
client connected (1)
ReadFile 1 msg (5 -> 05) : salut
ReadFile 2 msg (5 -> 10) : salut, c'e
ReadFile 2 msg (5 -> 15) : salut, c'est le
ReadFile 2 msg (5 -> 20) : salut, c'est le clie
ReadFile 2 msg (4 -> 24) : salut, c'est le client !
ReadFile2: ERROR_IO_PENDING
GQCIOS 0 255 003D3A18
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 4 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
What I do not understand is that even if I read all the data, ReadFile() still returns a pending operation (it's the "ReadFile2: ERROR_IO_PENDING" error message after the last "msg" output)
Is my loop wrong ? Do I misuse ReadFile() / GetQueuedCompletionStatus() ?
thank you
Where is your write related function? it seems that your code is in wrong order. In the _read_data_cb routine, GetQueuedCompletionStatus should be called first, then depending on the lpOverlapped parameter, the received data should be ready in the buffer that you specified in the ReadFile function. Since you're calling Readfile without checking whether OVERLAPPED is a overlapped structure for the send context or recv context, you're not getting the expected output. The following code should clear things up:
while(TRUE)
{
bReturnValue=GetQueuedCompletionStatus(pIOCPServer->m_pIOCP, &dwBytesTransferred,(DWORD *)pClient,reinterpret_cast<LPOVERLAPPED*>(&pOverlapped),INFINITE);
if(!bReturnValue)
{
if(NULL==pOverlapped)
continue;
else
break;
}
else
{
if(pOverlapped==NULL)
continue;
}
if(dwBytesTransferred==0)
break;
if(lpOverlapped==&(pClient->m_pRecvContext->overlapped))
pClient->handleRecvEvent(dwBytesTransferred)
else if(lpOverlapped==&(pClient->m_pSendContext->overlapped))
pClient->handleSendEvent(dwBytesTransferred)
}
...

Resources