Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing the close() function in Linux with my own close() function

I'm trying to provide my own implementation of the close() function in Linux. Why? Because I just found out you could do that and it sounds fun.

Here's myclose.c:

#include <stdio.h>

int close(int fd) {
    printf("Closing fd: %d\n", fd);
    return 0;
}

Here's my makefile:

all: myclose.so my-close.so

%.so: %.o
    gcc -shared -o $@ $<

%.o:%.c
    gcc -c -fPIC -o $@ $<

clean:
    rm -f *.so *.o

After compilation, I run:

export LD_PRELOAD=`pwd`/myclose.so

Then I run:

cat myclose.c

The output I get is:

#include <stdio.h>

int close(int fd) {
    printf("Closing fd: %d\n", fd);
    return 0;
}
Closing fd: 3

Yay! Works right? Almost. cat calls close() more than once, but we only see one line of output. According to strace (and common sense), close() should be called for file descriptors 1 and 2 as well. If I run cat * and cat all the files in the directory, I see "Closing fd: 3", "Closing fd: 4", etc. up to the last file in the directory. Since all of these file descriptors are greater than 2, I thought maybe there was an issue with closing the special file descriptors (stdout and stderr). However, when I run ls I only see the regular output and no "Closing fd:" lines, which means it didn't work for ls either, even though strace shows close(3) when running ls.

Any ideas on what could be wrong?

like image 660
gsingh2011 Avatar asked Apr 28 '14 16:04

gsingh2011


2 Answers

This kind of "replacement" only works for dynamically linked programs.

Any program being linked statical to the library implementing the close-call would fail to have it "replaced".

The latter will be the case for each call to close() out of the library implementing the orginal close() itself. And it also seems to be the case for the standard file descriptors 0, 1, and 2 as their closing most likely is implemented in the same library, that is in the libc implementation in use.

like image 97
alk Avatar answered Nov 06 '22 21:11

alk


I am surprised it worked as well as it did!

You are replacing the C library entry for close(), not the system call. However, other parts of the C library are still being used for those programs. Probably there is some direct linkage to the first 3 file handles. Have a look at the source of whichever C library you are using.

like image 45
wallyk Avatar answered Nov 06 '22 21:11

wallyk