Program break doesnt change after calling malloc in a loop? - c

Running this piece of code is supposed to cause program break to increase by about malloc_counts * _SC_PAGESIZE instead I get fixed program break each time, so why is this. malloc is supposed to call brk or sbrk which itself round up size passed to next page (with some extra work). So what's happening ?
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
int main(){
const long malloc_counts = 10;
printf("PAGE SIZE: %ld\n", sysconf(_SC_PAGESIZE));
void* allocated_pool[malloc_counts];
for(int counter=0; counter < malloc_counts; counter++)
{
printf("program brk: %p\n",sbrk(0));
allocated_pool[counter] = malloc(127*4096);
}
}

which i guess of course using optimizations
Your compiler optimizes the calls to malloc out, because they are unused. Because malloc calls are removed, nothing changes and the heap is not moved.
And glibc overallocates a lot, so the value has to be large enough for it to see it. And the default M_MMAP_THRESHOLD seem to be 128 * 1024. So you have to pick a value large enough, but below mmap threshold to see a difference in glibc.
Disable your compiler optimizations and allocate a lot and heap will be moved. Try the following:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("PAGE SIZE: %ld\n", sysconf(_SC_PAGESIZE));
#define malloc_counts 20
void *allocated_pool[malloc_counts];
for(int counter = 0; counter < malloc_counts; counter++) {
printf("program brk: %p\n", sbrk(0));
allocated_pool[counter] = malloc((size_t)127 * 1024);
*(void *volatile *)&allocated_pool[counter];
}
}

Related

Library interpositioning

I have been trying to intercept calls to malloc and free, following our textbook (CSAPP book).
I have followed their exact code, and nearly the same code that I found online and I keep getting a segmentation fault. I heard our professor saying something about printf that mallocs and frees memory so I think that this happens because I am intercepting a malloc and since I am using a printf function inside the intercepting function, it will call itself recursively.
However I can't seem to find a solution to solving this problem? Our professor demonstrated that intercepting worked ( he didn't show us the code) and prints our information every time a malloc occurs, so I do know that it's possible.
Can anyone suggest a working method??
Here is the code that I used and get nothing:
mymalloc.c
#ifdef RUNTIME
// Run-time interposition of malloc and free based on // dynamic linker's (ld-linux.so) LD_PRELOAD mechanism #define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h> #include <dlfcn.h>
void *malloc(size_t size) {
static void *(*mallocp)(size_t size) = NULL; char *error;
void *ptr;
// get address of libc malloc
if (!mallocp) {
mallocp = dlsym(RTLD_NEXT, "malloc"); if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(EXIT_FAILURE);
}
}
ptr = mallocp(size);
printf("malloc(%d) = %p\n", (int)size, ptr); return ptr;
}
#endif
test.c
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("main\n");
int* a = malloc(sizeof(int)*5);
a[0] = 1;
printf("end\n");
}
The result i'm getting:
$ gcc -o test test.c
$ gcc -DRUNTIME -shared -fPIC mymalloc.c -o mymalloc.so
$ LD_PRELOAD=./mymalloc.so ./test
Segmentation Fault
This is the code that I tried and got segmentation fault (from https://gist.github.com/iamben/4124829):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
static void* (*rmalloc)(size_t) = NULL;
void* p = NULL;
// resolve next malloc
if(!rmalloc) rmalloc = dlsym(RTLD_NEXT, "malloc");
// do actual malloc
p = rmalloc(size);
// show statistic
fprintf(stderr, "[MEM | malloc] Allocated: %lu bytes\n", size);
return p;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_LEN 128
int main(int argc, const char *argv[])
{
char *c;
char *str1 = "Hello ";
char *str2 = "World";
//allocate an empty string
c = malloc(STR_LEN * sizeof(char));
c[0] = 0x0;
//and concatenate str{1,2}
strcat(c, str1);
strcat(c, str2);
printf("New str: %s\n", c);
return 0;
}
The makefile from the git repo didn't work so I manually compiled the files and got:
$ gcc -shared -fPIC libint.c -o libint.so
$ gcc -o str str.c
$ LD_PRELOAD=./libint.so ./str
Segmentation fault
I have been doing this for hours and I still get the same incorrect result, despite the fact that I copied textbook code. I would really appreciate any help!!
One way to deal with this is to turn off the printf when your return is called recursively:
static char ACallIsInProgress = 0;
if (!ACallIsInProgress)
{
ACallIsInProgress = 1;
printf("malloc(%d) = %p\n", (int)size, ptr);
ACallIsInProgress = 0;
}
return ptr;
With this, if printf calls malloc, your routine will merely call the actual malloc (via mallocp) and return without causing another printf. You will miss printing information about a call to malloc that the printf does, but that is generally tolerable when interposing is being used to study the general program, not the C library.
If you need to support multithreading, some additional work might be needed.
The printf implementation might allocate a buffer only once, the first time it is used. In that case, you can initialize a flag that turns off the printf similar to the above, call printf once in the main routine (maybe be sure it includes a nice formatting task that causes printf to allocate a buffer, not a plain string), and then set the flag to turn on the printf call and leave it set for the rest of the program.
Another option is for your malloc routine not to use printf at all but to cache data in a buffer to be written later by some other routine or to write raw data to a file using write, with that data interpreted and formatted by a separate program later. Or the raw data could be written by a pipe to a program that formats and prints it and that is not using your interposed malloc.

Unknown Segmentation Fault (Core Dumped) in multithread initialization

I've had three different lab TAs look at my code and none of them have been able to help me, so I've decided to try here. Unless I delete all code relating to both gettimeofday and any semaphores, I get a "Segmentation fault (core dumped)​" error. I've boiled down my code to only the main thread with simple declarations to attempt to get to the root of the problem.
My code:
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/time.h>
void *threadN (void *); /* thread routines */
pthread_t tid[1]; /* array of thread IDs */
int main()
{
int i,j;
/* here create and initialize all semaphores */
int mutex = sem_create(777777, 1);
int MatrixA[6000][3000];
for (i=0; i < 6000; i++) {
for (j=0; j < 3000; j++) {
MatrixA[i][j]=i*j;
}
}
int MatrixB[3000][1000];
for (i=0; i < 3000; i++) {
for (j=0; j < 1000; j++) {
MatrixB[i][j]=i*j;
}
}
int MatrixC[6000][1000];
struct timeval tim;
gettimeofday(&tim, NULL);
float t1=tim.tv_sec+(tim.tv_usec/1000000.0);
gettimeofday(&tim, NULL);
float t2=tim.tv_sec+(tim.tv_usec/1000000.0);
printf("%.2lf seconds elapsed\n", t2-t1);
sem_rm(sem_open(777777, 1));
return 0;
}​
I'm completely stumped here.
You eat your stack. See Radix sort for 10^6 array in C, comment from #Joachim Pileborg:
Local variables are usually stored on the stack, and the stack is usually limited to single-digit megabytes. On Windows for example, the default is 1MB per process, on Linux the default is 8MB...
I tried your code on Windows and it was dead with just MatrixA defined: 6000*3000*4 (for int)...
So you will have to move matrix data out of stack: define matrix as static or allocate on heap.
A useful thing I have found for tracking seg faults is with using gdb.
gcc -g -o a.out -c program.c
-g generates source level debug information
gdb a.out core
this starts up gdb with a.out
(gdb) run
this should run the program and show the line where the seg fault is happening.

C: Run machine code from memory

I want to execute some code from memory; my longterm goal is to create a self-decrypting app. To understand the matter I started from the roots.
I created the following code:
#define UNENCRYPTED true
#define sizeof_function(x) ( (unsigned long) (&(endof_##x)) - (unsigned long) (&x))
#define endof_function(x) void volatile endof_##x() {}
#define DECLARE_END_OF_FUNCTION(x) void endof_##x();
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
unsigned char *bin;
#ifdef UNENCRYPTED
void hexdump(char *description, unsigned char *toDump, unsigned long length) {
printf("Hex-dump of \"%s\":\n", description);
for (int i = 0; i < length; i++) {
printf("%02x", toDump[i]);
}
printf("\n");
}
void hello_world() {
printf("Hello World!\n");
}
endof_function(hello_world);
#endif
int main (void) {
errno = 0;
unsigned long hello_worldSize = sizeof_function(hello_world);
bin = malloc(hello_worldSize);
//Compute the start of the page
size_t pagesize = sysconf(_SC_PAGESIZE);
uintptr_t start = (uintptr_t) bin;
uintptr_t end = start + (hello_worldSize);
uintptr_t pagestart = start & -pagesize;
bin = (void *)pagestart;
//Set mprotect for bin to write-only
if(mprotect(bin, end - pagestart, PROT_WRITE) == -1) {
printf("\"mprotect\" failed; error: %s\n", strerror(errno));
return(1);
}
//Get size and adresses
unsigned long hello_worldAdress = (uintptr_t)&hello_world;
unsigned long binAdress = (uintptr_t)bin;
printf("Address of hello_world %lu\nSize of hello_world %lu\nAdress of bin:%lu\n", hello_worldAdress, hello_worldSize, binAdress);
//Check if hello_worldAdress really points to hello_world()
void (*checkAdress)(void) = (void *)hello_worldAdress;
checkAdress();
//Print memory contents of hello_world()
hexdump("hello_world", (void *)&hello_world, hello_worldSize);
//Copy hello_world() to bin
memcpy(bin, (void *)hello_worldAdress, hello_worldSize);
//Set mprotect for bin to read-execute
if(mprotect(bin, end - pagestart, PROT_READ|PROT_EXEC) == -1) {
printf("\"mprotect\" failed; error: %s\n", strerror(errno));
return(1);
}
//Check if the contents at binAdress are the same as of hello_world
hexdump("bin", (void *)binAdress, hello_worldSize);
//Execute binAdress
void (*executeBin)(void) = (void *)binAdress;
executeBin();
return(0);
}
However I get an segfault-error; the programs output is the following:
(On OS X; i86-64):
Adress of hello_world 4294970639
Size of hello_world 17
Adress of bin:4296028160
Hello World!
Hex-dump of "hello_world":
554889e5488d3d670200005de95a010000
Hex-dump of "bin":
554889e5488d3d670200005de95a010000
Program ended with exit code: 9
And on my Raspi (Linux with 32-Bit ARM):
Adress of hello_world 67688
Size of hello_world 36
Hello World!
Hello World!
Hex-dump of "hello_world":
00482de90db0a0e108d04de20c009fe512ffffeb04008de50bd0a0e10088bde8d20b0100
Hex-dump of "bin":
00482de90db0a0e108d04de20c009fe512ffffeb04008de50bd0a0e10088bde8d20b0100
Speicherzugriffsfehler //This is german for memory access error
Where is my mistake?
The problem was, that the printf-call in hello_world is based on a relative jump address, which of course doesn't work in the copied function.
For testing purposes I changed hello_world to:
int hello_world() {
//_printf("Hello World!\n");
return 14;
}
and the code under "//Execute binAdress" to:
int (*executeBin)(void) = (void *)binAdress;
int test = executeBin();
printf("Value: %i\n", test);
which prints out 14 :D
On ARM, you have to flush the instruction cache using a function like cacheflush, or your code may not run properly. This is required for self-modifying code and JIT compilers, but is not generally needed for x86.
Additionally, if you move a chunk of code from one location to another, you have to fixup any relative jumps. Typically, calls to library functions are implemented as jumps to a relocation section, and are often relative.
To avoid having to fixup jumps, you can use some linker tricks to compile code to start at a different offset. Then, when decrypting, you simply load the decrypted code to that offset. A two-stage compilation process is usually used: compile your real code, append the resulting machine code to your decryption stub, and compile the whole program.

Different run time after Segfault in Infinite Recursive main()

Just as we know,
In Linux world, infinite recusive "main()" in userspace will receive "segmentation fault" messsage, which is actually caused by stack overflow. (just as the following code)
#include <stdio.h>
void main(void)
{
main ();
}
Experiment and Question:
Change code to:
#include <stdio.h>
int cnt = 0;
void main(void) {
printf("cnt %d\n", cnt++);
main();
}
Test environment:
x86-64 ubuntu,
gcc-4.6
I need your help and thanks in advance!
Why Segmentation fault happens in different "cnt" value:
cnt: 523614
cnt: 523602
cnt: 523712
cnt: 523671
This is probably due to Address space layout randomization. If you run the slightly modified example of your program:
#include <stdio.h>
int cnt = 0;
void main(void)
{
int a;
printf("cnt %d %p\n", cnt++, (void*)&a); fflush(stdout);
main();
}
you will see that the address of a is not consistent over various runs of the program. Probably the initial size of the stack is also slightly randomized resulting in a slightly different number of stack frames fitting in this space.
P.S: I've added a fflush so the output of the program can be safely piped through for example tail and grep, otherwise buffering may blur the actual last line of output.
P.S2: I had to change print into printf and add #include <stdio.h>.
P.S3: You should not use an optimization on your program, because otherwise a tail-call optimization will remove your recursion and your program will actually loop forever. My version of the program doesn't do that, because of the aliased a.

Find program's code address at runtime?

When I use gdb to debug a program written in C, the command disassemble shows the codes and their addresses in the code memory segmentation. Is it possible to know those memory addresses at runtime? I am using Ubuntu OS. Thank you.
[edit] To be more specific, I will demonstrate it with following example.
#include <stdio.h>
int main(int argc,char *argv[]){
myfunction();
exit(0);
}
Now I would like to have the address of myfunction() in the code memory segmentation when I run my program.
Above answer is vastly overcomplicated. If the function reference is static, as it is above, the address is simply the value of the symbol name in pointer context:
void* myfunction_address = myfunction;
If you are grabbing the function dynamically out of a shared library, then the value returned from dlsym() (POSIX) or GetProcAddress() (windows) is likewise the address of the function.
Note that the above code is likely to generate a warning with some compilers, as ISO C technically forbids assignment between code and data pointers (some architectures put them in physically distinct address spaces).
And some pedants will point out that the address returned isn't really guaranteed to be the memory address of the function, it's just a unique value that can be compared for equality with other function pointers and acts, when called, to transfer control to the function whose pointer it holds. Obviously all known compilers implement this with a branch target address.
And finally, note that the "address" of a function is a little ambiguous. If the function was loaded dynamically or is an extern reference to an exported symbol, what you really get is generally a pointer to some fixup code in the "PLT" (a Unix/ELF term, though the PE/COFF mechanism on windows is similar) that then jumps to the function.
If you know the function name before program runs, simply use
void * addr = myfunction;
If the function name is given at run-time, I once wrote a function to find out the symbol address dynamically using bfd library. Here is the x86_64 code, you can get the address via find_symbol("a.out", "myfunction") in the example.
#include <bfd.h>
#include <stdio.h>
#include <stdlib.h>
#include <type.h>
#include <string.h>
long find_symbol(char *filename, char *symname)
{
bfd *ibfd;
asymbol **symtab;
long nsize, nsyms, i;
symbol_info syminfo;
char **matching;
bfd_init();
ibfd = bfd_openr(filename, NULL);
if (ibfd == NULL) {
printf("bfd_openr error\n");
}
if (!bfd_check_format_matches(ibfd, bfd_object, &matching)) {
printf("format_matches\n");
}
nsize = bfd_get_symtab_upper_bound (ibfd);
symtab = malloc(nsize);
nsyms = bfd_canonicalize_symtab(ibfd, symtab);
for (i = 0; i < nsyms; i++) {
if (strcmp(symtab[i]->name, symname) == 0) {
bfd_symbol_info(symtab[i], &syminfo);
return (long) syminfo.value;
}
}
bfd_close(ibfd);
printf("cannot find symbol\n");
}
To get a backtrace, use execinfo.h as documented in the GNU libc manual.
For example:
#include <execinfo.h>
#include <stdio.h>
#include <unistd.h>
void trace_pom()
{
const int sz = 15;
void *buf[sz];
// get at most sz entries
int n = backtrace(buf, sz);
// output them right to stderr
backtrace_symbols_fd(buf, n, fileno(stderr));
// but if you want to output the strings yourself
// you may use char ** backtrace_symbols (void *const *buffer, int size)
write(fileno(stderr), "\n", 1);
}
void TransferFunds(int n);
void DepositMoney(int n)
{
if (n <= 0)
trace_pom();
else TransferFunds(n-1);
}
void TransferFunds(int n)
{
DepositMoney(n);
}
int main()
{
DepositMoney(3);
return 0;
}
compiled
gcc a.c -o a -g -Wall -Werror -rdynamic
According to the mentioned website:
Currently, the function name and offset only be obtained on systems that use the ELF
binary format for programs and libraries. On other systems, only the hexadecimal return
address will be present. Also, you may need to pass additional flags to the linker to
make the function names available to the program. (For example, on systems using GNU
ld, you must pass (-rdynamic.)
Output
./a(trace_pom+0xc9)[0x80487fd]
./a(DepositMoney+0x11)[0x8048862]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(main+0x1d)[0x80488a4]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e16775]
./a[0x80486a1]
About a comment in an answer (getting the address of an instruction), you can use this very ugly trick
#include <setjmp.h>
void function() {
printf("in function\n");
printf("%d\n",__LINE__);
printf("exiting function\n");
}
int main() {
jmp_buf env;
int i;
printf("in main\n");
printf("%d\n",__LINE__);
printf("calling function\n");
setjmp(env);
for (i=0; i < 18; ++i) {
printf("%p\n",env[i]);
}
function();
printf("in main again\n");
printf("%d\n",__LINE__);
}
It should be env[12] (the eip), but be careful as it looks machine dependent, so triple check my word. This is the output
in main
13
calling function
0xbfff037f
0x0
0x1f80
0x1dcb
0x4
0x8fe2f50c
0x0
0x0
0xbffff2a8
0xbffff240
0x1f
0x292
0x1e09
0x17
0x8fe0001f
0x1f
0x0
0x37
in function
4
exiting function
in main again
37
have fun!

Resources