Unable to intercept openat
syscall made by dlopen
#118
Description
I am trying to intercept all openat
syscalls. This involves those made by dlopen
when loading shared libraries in the program.
What I have noticed is that I am able to intercept openat
if I explicitly call this function from my application. However, if I try to open a .so
using dlopen
which internally should still call openat
(ref:) then it does not intercept and goes on to make the syscall
as usual.
I inspected the disassembly and noticed that even though __open64_nocancel
is being hotpatched and the syscall
is replaced by jmp
, this is done in the __open64_nocancel
in libc.so
. However, when I call dlopen
, it ends up calling __open64_nocancel
from ld-linux-x86-64.so.2
which does not seem to have the hotpatch.
Below is a screenshot showing the disassembly:
This is the screenshot of the hotpatched instance:
This is the screenshot showing these __open64_nocancel
are in apparently two different .so
files:
Is there any guess on why:
a) There are two instances of __open64_nocancel
? ld.so
is supposed to load these so not sure why these come up as duplicates.
b) Only one of the two instances was hotpatched?
Here is a sample application I am using:
#include <string>
#include <iostream>
#include <dlfcn.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int test_openat() {
int fd = openat(AT_FDCWD, "/home/gochaudh/.local/lib/python3.10/site-packages/pandas/io/__pycache__/parquet.cpython-310.pyc", O_RDONLY|O_CLOEXEC);
if (fd != -1) {
std::cout << "Opened file at: " << fd << std::endl;
} else {
std::cerr << "Cannot open file" << std::endl;
perror("openat");
return -1;
}
int ret = close(fd);
if (!ret) {
std::cout << "File closed" << std::endl;
} else {
std::cerr << "Cannot close file" << std::endl;
return -1;
}
return 0;
}
int test_dlopen() {
const std::string lib_path("/home/gochaudh/functions_kernel/lib/python/3.10.0/lib/libpython3.10.so.1.0");
void *lib = dlopen(lib_path.c_str(), RTLD_NOW);
if (lib) {
std::cout << "Library loaded at: " << lib << std::endl;
} else {
std::cerr << "Could not open library: " << dlerror() << std::endl;
return -1;
}
int ret = dlclose(lib);
if (!ret) {
std::cout << "Library closed" << std::endl;
} else {
std::cerr << "Cannot close library" << std::endl;
return -1;
}
return 0;
}
int main() {
test_openat();
test_dlopen();
return 0;
}