-
-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OOM in Linux Mode #218
Comments
First of all, thank you for trying out the tool and for filing a very detailed issue 🥳 Tagging @jasocrow (one of the coauthor of the Linux mode) in case you've seen this before / you get what's going on. I'll take a look in the next few days - hopefully we can figure out what's going on :) Cheers |
In the case where you don't increase the VM memory, the OOM gets triggered before the breakpoint gets hit? Also, this bit of output seems potentially interesting; do you know where
In the next log, it looks like you do it the breakpoint but it seems to hang after the It looks like I guess one thing you can try is to manually add a Does this make sense? Cheers |
Thank you for your time. It seems that the OOM gets triggered before the breakpoint :
So our breakpoint is at Looking at the proc mapping and the symbol mapping
This is called in the TIFF *
TIFFClientOpen(
const char *name, const char *mode,
thandle_t clientdata,
TIFFReadWriteProc readproc,
TIFFReadWriteProc writeproc,
TIFFSeekProc seekproc,
TIFFCloseProc closeproc,
TIFFSizeProc sizeproc,
TIFFMapFileProc mapproc,
TIFFUnmapFileProc unmapproc)
{
static const char module[] = "TIFFClientOpen";
TIFF *tif;
int m;
const char *cp;
...
m = _TIFFgetMode(mode, module); <----- HERE
if (m == -1)
goto bad2;
tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof(TIFF) + strlen(name) + 1));
if (tif == NULL)
{
TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
goto bad2;
}
... The int _TIFFgetMode(const char *mode, const char *module)
{
int m = -1;
switch (mode[0])
{
case 'r':
m = O_RDONLY;
if (mode[1] == '+')
m = O_RDWR;
break;
case 'w':
case 'a':
m = O_RDWR | O_CREAT;
if (mode[0] == 'w')
m |= O_TRUNC;
break;
default:
TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
break;
}
return (m);
} Calling
|
All right - it'll probably easier if I make a repro environment to experiment a bit / see if I run into the same issue. Will follow your instructions. Cheers |
Okay I've successfully set-up an environment and I'm able to see what you're seeing - thanks again for the detailed instructions! Will update this issue when / once I know more. Cheers |
I've spent a bit of time on this but I still don't understand what's the issue. I've seen the same thing as you; artificially inserting a Here are a few other things I've done:
At this point I wonder if there's not a bug with the shellcode that gets injected in the target; at least I'm going to spend a bit more time trying to do that. Cheers |
Thanks for the detailed report. I haven't come across this issue before. I'll plan to take a look at this soon. |
I've tried yesterday to insert an
So at this point, it seems unlikely that the shellcode injection is to blame.. back to the drawing board I think. Cheers |
Okay so after checking the disassembly of the // Linux kernel has a bug that leads to kernel deadlock if a process
// maps TBs of memory and then calls mlock().
static void MlockIsUnsupported() {
static atomic_uint8_t printed;
if (atomic_exchange(&printed, 1, memory_order_relaxed))
return;
VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
SanitizerToolName);
}
INTERCEPTOR(int, mlock, const void *addr, uptr len) {
MlockIsUnsupported();
return 0;
} 😅 Do you see the same?
If I insert this line instead..:
..I get a consistent behavior with
So at least, now we have the same behavior w/ & w/o @jasocrow have you tried running the Linux mode on ASAN instrumented binaries by any chance? Cheers |
Just curious @jasocrow , How important is it to call mlockall inside the process? I don't believe the VM image uses any swap and I suspect that address sanitizer allocates a fair bit of memory for its shadow pages that is never expected to physically reside anywhere and is likely the main reason why they intercept all mlock related calls (since mlocking TBs of memory will most certianly OOM the machine). I created a quick example using LLVM's address sanitizer in clang: #include <stdio.h>
#include <stdlib.h>
void do_crash_test(char* input) {
if (input[0] == 'e') {
if (input[1] == 's') {
if (input[2] == 'c') {
*(char*)NULL = 1;
}
}
}
if (input[0] == '1') {
if (input[1] == '2') {
if (input[2] == '3') {
char* x = malloc(11);
x[12] = 1;
}
}
}
}
void end_crash_test() { printf("End crash test.\n"); }
int main(int argc, char* argv[]) {
char* buf = NULL;
size_t cbBuf = 10;
ssize_t cbRead = 0;
buf = (char*)calloc(1, cbBuf);
if (!buf) {
printf("calloc failed.\n");
goto END;
}
printf("Enter some input.\n");
cbRead = getline(&buf, &cbBuf, stdin);
if (-1 == cbRead) {
perror("getline failure: ");
goto END;
}
do_crash_test(buf);
end_crash_test();
END:
if (buf) {
free(buf);
}
} compiled using:
Running that code above using the gdb scripts calling mlockall does indeed OOM the machine. #if not self.mlock:
#self.call_mlockall()
#self.mlock = True
#return False
#self.restore_orig_bytes() The snapshot passes and the fuzzer finds both the null deref and OOB-write:
I'm not sure how much non-committed (over-commited?) memory libtiff allocates but if its also unreasonably large to force it into physical memory via mlock then i'd expect you'd likely see the same issue? idk. I'm also keen on getting ASAN to work reliably here :) ¯\_(ツ)_/¯ best, |
Yeah I'm kind of wondering if we just shouldn't disable I personally haven't played too much with the Linux stuff so I'd leave it to the people that have used it more to know if it's the right call. Thanks for sharing your experiments @defparam 🙏🏽 Cheers |
Sorry for the late response. I haven't tried fuzzing using ASAN.
|
Hello, thanks for the great tool !
I am trying to reproduce a bug in libtiff 4.0.4 with linux mode, but I can't manage to get a proper snapshot of my VM because of an out of memory error.
Target
I downloaded and compiled libtiff with the following commands :
I then created the following GDB QEMU script :
Environment
Tested on main branch version 0.5.5 :
I created two scripts to simplify the snapshotting process :
linux_mode/libtiff/snapshot_client.sh
:linux_mode/libtiff/snapshot_server.sh
:Taking the snapshot
Launching first our server and running our program, we can successfully see our function getting break'ed on :
But then repeating the operation with the client launched :
I tried increasing the VM allocated memory size but the OOM just takes longer to come.
The client just hangs :
This may be related to my binary, but on my host I don't have this problem at all with the same command. I have no idea how to debug this issue, if you could maybe guide me ? Let me know if I forgot some context/details.
Thanks !
The text was updated successfully, but these errors were encountered: