Zlib Calling deflateInit function always returning Z_MEM_ERROR - zlib

I am using zlib-1.2.8 and I am calling compress2(dest, destLen, source, sourceLen, level) from compress.c in my code for compressing the data.
The function compress2 (dest, destLen, source, sourceLen, level) is calling
deflateInit(&stream, level);
deflateInit is macro.
#define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
That is compress2 is calling deflateInit_.
My Problem is deflateInit_ is returning Z_MEM_ERROR.
I am trying to debug inside deflateInit_ but not got any debug messages that I have put there.
Also I commented all the exising code inside function deflateInit_ and return different error from the function ie Z_BUF_ERROR but still deflateInit_ is returning Z_MEM_ERROR.
Here if I am explicty returing Z_BUF_ERROR still I am getting Z_MEM_ERROR.
Please give me some pointers behind this behaviour.

It means what it says. zlib is calling malloc(), which is returning NULL. That is presumably because there is not enough memory availabel to malloc() to honor the request. deflate with the default parameters needs to allocate about 260K to function.

Related

blocking call to `dlsym` (RTLD_NEXT)

I am trying to wrap function. To do that I thought about using dlsym to get the real function location in memory after having injected my dynamic library.
I am running on MacOS Mojave (10.14.6) with Apple clang version 11.0.0 (clang-1100.0.33.8).
I tried to run a rather simple code displaying a message each time malloc was called.
So I used the code of this post : Overriding 'malloc' using the LD_PRELOAD mechanism
My test code was :
#include <stdlib.h>
int main()
{
(void)malloc(1);
(void)malloc(1);
return (0);
}
I injected the dynamic library using DYLD_INSERT_LIBRARIES=./mylib.so DYLD_FORCE_FLAT_NAMESPACE=1 on OSX and LD_PRELOAD=./mylib.so on Ubuntu.
On OSX, the program is blocking on the dlsym call where as on a Ubuntu docker box, the program works fine.
EDIT:
As #R.. pointed out, the dlsym implementation on OSX is calling malloc (see sources : https://opensource.apple.com/source/cctools/cctools-667.8.0/libdyld/dlopen.c)
It's likely that calling dlsym causes a recursive call to malloc, which in turn causes a recursive call to dlsym, which deadlocks the second time because it already holds some lock. Using preload libraries to wrap malloc, rather than fully replacing it, is generally a bad idea, for this and other reasons.
You might be able to use LD_AUDIT or the equivalent functionality on OSX (if any) to print a trace of when malloc is called. Otherwise you could drop in a full replacement malloc with debug output.
You may also be falling into infinite recursion due to calling fprintf(), so using this code to interpose on malloc() is dangerous (copied from the linked question):
void *malloc(size_t size)
{
void *p = NULL;
fprintf(stderr, "malloc(%d) = ", size);
p = real_malloc(size);
fprintf(stderr, "%p\n", p);
return p;
}
Library code such as fprintf() is likely to call malloc().

Force function to return

For an analysis I'm doing I want to be able to "catch" specific malloc calls. I therefore created a function wrapper to malloc, named malloc_wrapper:
void *malloc_wrap(size_t size) {
return malloc(size);
}
All left is just slightly modify the source code by switching some malloc calls with malloc_wrap. I then use Intel Pin to capture what I need.
Unfortunately, it didn't work. I didn't see malloc_wrap being called in the assembly code, so it was probably inlined. Quick search, and I added this to the function header:
__attribute__ ((noinline))
Great, now I'm able to spot the function entry, but not the exit. I can't see any ret call at the end of the function. How can I force the compiler to compile my wrapper function regularly?

Calling function without parameters when the definition includes parameters

I'm trying to run an old MUD driver compiled with added -g flag and removed -O2 flag, so that I can debug it. I have a function with a prototype void try_to_swap(void), but the definition is void try_to_swap(volatile int* interrupted). Inside the function the value of that pointer is checked:
if(*interrupted)
...
The function is called without parameters, like the prototype - try_to_swap();
Everything works OK with the optimization flag. But without it I get a SIGSEGV when the function is called. The problem is that the pointer points to an address which is unreachable for the process (0x3b - every time), thus the segmentation fault.
My question is:
a) Why don't I get any errors during make? Shouldn't the lack of the parameter in the call be somehow noticed by the compiler?
b) During optimization, does the compiler somehow take care of the value of the pointer so the program won't crash?
c) What would be the right way to tackle this? Remove the pointer from definiton, add it to the prototype? The pointer is used only in this function, and only in mentioned if. It doesn't seem to be initialized anywhere. Or maybe it's somehow automatically initialized? I'm not too familiar with volatile pointers. But the pointer value is random garbage from the stack set before the function call, as no parameter value was provided. Is this even legal in C, where default values are not an option?
a) In C, () means "any arguments" and isn't the same as (void) which is no argument. try_to_swap() is valid but not a good documentation for users.
b) Yes, the compiler seems to detect the missing parameter and just passes a null pointer.
c) You could add the pointer argument to the prototype and pass what's required by the internal if or try a trick.

How to include C backtrace in a kernel module code?

So I am trying to find out what kernel processes are calling some functions in a block driver. I thought including backtrace() in the C library would make it easy. But I am having trouble to load the backtrace.
I copied this example function to show the backtrace:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html
All attempts to compile have error in one place or another that a file cannot be found or that the functions are not defined.
Here is what comes closest.
In the Makefile I put the compiler directives:
-rdynamic -I/usr/include
If I leave out the second one, -I/usr/include, then the compiler reports it cannot find the required header execinfo.h.
Next, in the code where I want to do the backtrace I have copied the function from the example:
//trying to include the c backtrace capability
#include <execinfo.h>
void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
I have put the call to this function later on, in a block driver function where the first sign of the error happens. Simply:
show_stackframe();
So when I compile it, the following errors:
user#slinux:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
from /usr/include/execinfo.h:22,
from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: warning: "__always_inline" redefined
In file included from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc.h:86,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler.h:40,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/stddef.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/list.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/module.h:9,
from /home/linux/2.6-32/inc/linux_ver.h:40,
from /home/linux/2.6-32/block/block26.c:32:
/usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc4.h:15:1: warning: this is the location of the previous definition
/home/linux/2.6-32/block/block26.c:50: warning: function declaration isn’t a prototype
WARNING: "backtrace" [/home/linux/2.6-32/ndas_block.ko] undefined!
WARNING: "backtrace_symbols" [/home/linux/2.6-32/ndas_block.ko] undefined!
Note: block26.c is the file I am hoping to get the backtrace from.
Is there an obvious reason why the backtrace and backtrace_symbols remain undefined when it is compiled into the .ko modules?
I am guessing it because I use the compiler include execinfo.h which is residing on the computer and not being loaded to the module.
It is my uneducated guess to say the least.
Can anyone offer a help to get the backtrace functions loading up in the module?
Thanks for looking at this inquiry.
I am working on debian. When I take out the function and such, the module compiles fine and almost works perfectly.
From ndasusers
To print the stack contents and a backtrace to the kernel log, use the dump_stack() function in your kernel module. It's declared in linux/kernel.h in the include folder in the kernel source directory.
If you need to save the stack trace and process its elements somehow, save_stack_trace() or dump_trace() might be also an option. These functions are declared in <linux/stacktrace.h> and <asm/stacktrace.h>, respectively.
It is not as easy to use these as dump_stack() but if you need more flexibility, they may be helpful.
Here is how save_stack_trace() can be used (replace HOW_MANY_ENTRIES_TO_STORE with the value that suits your needs, 16-32 is usually more than enough):
unsigned long stack_entries[HOW_MANY_ENTRIES_TO_STORE];
struct stack_trace trace = {
.nr_entries = 0,
.entries = &stack_entries[0],
.max_entries = HOW_MANY_ENTRIES_TO_STORE,
/* How many "lower entries" to skip. */
.skip = 0
};
save_stack_trace(&trace);
Now stack_entries array contains the appropriate call addresses. The number of elements filled is nr_entries.
One more thing to point out. If it is desirable not to output the stack entries that belong to the implementation of save_stack_trace(), dump_trace() or dump_stack() themselves (on different systems, the number of such entries may vary), the following trick can be applied if you use save_stack_trace(). You can use __builtin_return_address(0) as an "anchor" entry and process only the entries "not lower" than that.
I know this question is about Linux, but since it's the first result for "backtrace kernel", here's a few more solutions:
DragonFly BSD
It's print_backtrace(int count) from /sys/sys/systm.h. It's implemented in
/sys/kern/kern_debug.c and/or /sys/platform/pc64/x86_64/db_trace.c. It can be found by searching for panic, which is implemented in /sys/kern/kern_shutdown.c, and calls print_backtrace(6) if DDB is defined and trace_on_panic is set, which are both defaults.
FreeBSD
It's kdb_backtrace(void) from /sys/sys/kdb.h. Likewise, it's easy to find by looking into what the panic implementation calls when trace_on_panic is true.
OpenBSD
Going the panic route, it appears to be db_stack_dump(), implemented in /sys/ddb/db_output.c. The only header mention is /sys/ddb/db_output.h.
dump_stack() is function can be used to print your stack and thus can be used to backtrack . while using it be carefull that don't put it in repetitive path like loops or packet receive function it can fill your dmesg buffer can cause crash in embedded device (having less memory and cpu).
This function is declared in linux/kernel.h .

weird stack corruption due to a dll call

I'm trying to make a call to a DLL function (via GetProcAddress etc) from C, using lcc compiler. The function gets called and everything goes well, but it looks like the top of the stack gets corrupted. I've tried to play with calling conventions (__stdcall / __cdecl), but that didn't help.
Unfortunately I don't have access to the dll code, and have to use the lcc compiler.
I found that this simple hack avoids stack corruption:
void foo(params)
{
int dummy;
dll_foo(params);
}
Here dll_foo is the pointer returned by GetProcAddress, and the stack is kind of protected by the dummy variable. So it's not the stack pointer that gets corrupted, but the data at the top of the stack. It works like this, but I'd like to know the reason of the corruption.
Any ideas?
UPD:
As asked in the comments, here are the actual function types:
typedef unsigned char (CALLBACK Tfr)(unsigned char);
typedef void (CALLBACK Tfw)(unsigned char,unsigned char);
typedef int (CALLBACK Tfs)(int);
typedef void (CALLBACK Tfwf)(int*,int);
All they show a similar behavior.
Unfortunately, it is not so straightforward to attach a debugger, as the code is compiled and launched by Matlab, using the LCC compiler, and there is no debugging support. Probably I will have to reproduce this problem in a standalone configuration, but it is not that easy to make it.
Sounds like you use MSVC, Debug + Windows + Registers. Look at the value of ESP before and after the call. If it doesn't match then first change the calling convention in the function pointer declaration (did you do that right?) If it still doesn't match then it is __stdcall and you haven't guessed the arguments you need to pass correctly.
Or the function could just clobbers the stack frame, it isn't impossible.
Posting your function pointer declaration that shows the real arguments would probably help diagnose this better.
It sounds to me like you were on the right track with looking at the calling convention. The main thing you need to do is ensure that the caller and callee are both using the same convention. Typically for a DLL, you want to use __stdcall for both, but if (as you say) you have no control over the DLL, then you need to modify your code to match what it's doing. Unfortunately, it's almost impossible to guess what that is -- I'm pretty sure lcc (like most C and C++ compilers) can produce code to use a variety of conventions.
Based on your hack working by putting an extra dword on the stack, it sounds like you currently have a mismatch where both the caller and the callee are trying to clear arguments off the stack (e.g., the caller using __cdecl and the callee using __stdcall.
You could try to "follow" the call to dll_foo() i assembler using a debugger, at check out exactly what the routine does stack-wise.

Resources