Skip to content

Commit

Permalink
support __xstat, __fxstat, __lxstat and __fxstatat
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilKoe committed Jan 22, 2024
1 parent c92b759 commit 7004b7b
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 0 deletions.
1 change: 1 addition & 0 deletions libiotrace/scripts/dev/gen_fnres_fctname_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"__open", "__open64", "__open_2", "__open64_2", # Hardened functions (`-D_FORTIFY_SOURCE=2`)

"stat", "fstat", "lstat", "fstatat",
"__xstat", "__fxstat", "__lxstat", "__fxstatat",

# - Pseudo-files -
"epoll_create", "epoll_create1",
Expand Down
4 changes: 4 additions & 0 deletions libiotrace/src/fnres/fctnconsts.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ static uint64_t hash_string(const char *str) {
#define CASE_FSTAT 0x310f75cd87
#define CASE_LSTAT 0x310fe2608d
#define CASE_FSTATAT 0xd0b2c41f583c
#define CASE___XSTAT 0xd0b07af2c337
#define CASE___FXSTAT 0x1ae6bfafa88bbd
#define CASE___LXSTAT 0x1ae6bfbda77f83
#define CASE___FXSTATAT 0x726f956a3bfa7bf2
#define CASE_EPOLL_CREATE 0xd13de43412238a74
#define CASE_EPOLL_CREATE1 0xf8fa6ab65694d925
#define CASE_EVENTFD 0xd0b27d1c4751
Expand Down
4 changes: 4 additions & 0 deletions libiotrace/src/fnres/fnres.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ int fnres_trace_ioevent(struct basic *ioevent_ptr) {

/* --- Functions relevant for tracing + traceable --- */
case CASE_FSTATAT:
case CASE___FXSTATAT:
{
struct fstatat_function *fstatat_function_data = ((struct fstatat_function*)ioevent_ptr->__function_data);
if(fstatat_function_data->flags.at_empty_path && '\0' == fstatat_function_data->file_name[0])
Expand All @@ -145,8 +146,10 @@ int fnres_trace_ioevent(struct basic *ioevent_ptr) {
}
}
case CASE_STAT:
case CASE___XSTAT:
case_like_stat:
case CASE_LSTAT:
case CASE___LXSTAT:
{

const char* const extracted_fname = get_file_name_from_ioevent_function_data(ioevent_ptr);
Expand Down Expand Up @@ -414,6 +417,7 @@ int fnres_trace_ioevent(struct basic *ioevent_ptr) {

case_fcntl_no_dup:
case CASE_FSTAT:
case CASE___FXSTAT:
case_like_fstat:
case CASE_READ:
case CASE_WRITE:
Expand Down
168 changes: 168 additions & 0 deletions libiotrace/src/posix_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,16 @@ REAL_DEFINITION_TYPE int REAL_DEFINITION(recvmmsg)(int sockfd, struct mmsghdr *m
REAL_DEFINITION_TYPE int REAL_DEFINITION(recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout) REAL_DEFINITION_INIT;
#endif
#endif
REAL_DEFINITION_TYPE int REAL_DEFINITION(__xstat)(const char *pathname, struct stat *statbuf) REAL_DEFINITION_INIT;
REAL_DEFINITION_TYPE int REAL_DEFINITION(stat)(const char *pathname, struct stat *statbuf) REAL_DEFINITION_INIT;
REAL_DEFINITION_TYPE int REAL_DEFINITION(__fxstat)(int fd, struct stat *statbuf) REAL_DEFINITION_INIT;
REAL_DEFINITION_TYPE int REAL_DEFINITION(fstat)(int fd, struct stat *statbuf) REAL_DEFINITION_INIT;
#ifdef HAVE_LSTAT
REAL_DEFINITION_TYPE int REAL_DEFINITION(__lxstat)(const char *pathname, struct stat *statbuf) REAL_DEFINITION_INIT;
REAL_DEFINITION_TYPE int REAL_DEFINITION(lstat)(const char *pathname, struct stat *statbuf) REAL_DEFINITION_INIT;
#endif
#ifdef HAVE_FSTATAT
REAL_DEFINITION_TYPE int REAL_DEFINITION(__fxstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags) REAL_DEFINITION_INIT;
REAL_DEFINITION_TYPE int REAL_DEFINITION(fstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags) REAL_DEFINITION_INIT;
#endif

Expand Down Expand Up @@ -4044,6 +4048,47 @@ int WRAP(recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
}
#endif

int WRAP(__xstat)(const char *pathname, struct stat *statbuf)
{
int ret;
struct basic data;
struct stat_function stat_function_data;
WRAP_START(data)

get_basic(&data);
LIBIOTRACE_STRUCT_SET_VOID_P(data, function_data, stat_function,
stat_function_data)
POSIX_IO_SET_FUNCTION_NAME(data.function_name);
LIBIOTRACE_STRUCT_SET_VOID_P_NULL(data, file_type)
stat_function_data.file_name = pathname;

CALL_REAL_FUNCTION_RET(data, ret, stat, pathname, statbuf)

if (-1 == ret)
{
data.return_state = error;
stat_function_data.type = unknown_stat_file_type;
stat_function_data.id.device_id = 0;
stat_function_data.id.inode_nr = 0;
stat_function_data.size = 0;
stat_function_data.blocksize = 0;
stat_function_data.allocated_512B_blocks = 0;
}
else
{
data.return_state = ok;
stat_function_data.type = get_stat_file_type(statbuf->st_mode);
stat_function_data.id.device_id = statbuf->st_dev;
stat_function_data.id.inode_nr = statbuf->st_ino;
stat_function_data.size = statbuf->st_size;
stat_function_data.blocksize = statbuf->st_blksize;
stat_function_data.allocated_512B_blocks = statbuf->st_blocks;
}

WRAP_END(data, stat)
return ret;
}

int WRAP(stat)(const char *pathname, struct stat *statbuf)
{
int ret;
Expand Down Expand Up @@ -4085,6 +4130,45 @@ int WRAP(stat)(const char *pathname, struct stat *statbuf)
return ret;
}

int WRAP(__fxstat)(int fd, struct stat *statbuf)
{
int ret;
struct basic data;
struct file_descriptor file_descriptor_data;
struct fstat_function fstat_function_data;
WRAP_START(data)

get_basic(&data);
LIBIOTRACE_STRUCT_SET_VOID_P(data, function_data, fstat_function,
fstat_function_data)
POSIX_IO_SET_FUNCTION_NAME(data.function_name);
file_descriptor_data.descriptor = fd;
LIBIOTRACE_STRUCT_SET_VOID_P(data, file_type, file_descriptor,
file_descriptor_data)

CALL_REAL_FUNCTION_RET(data, ret, fstat, fd, statbuf)

if (-1 == ret)
{
data.return_state = error;
fstat_function_data.type = unknown_stat_file_type;
fstat_function_data.size = 0;
fstat_function_data.blocksize = 0;
fstat_function_data.allocated_512B_blocks = 0;
}
else
{
data.return_state = ok;
fstat_function_data.type = get_stat_file_type(statbuf->st_mode);
fstat_function_data.size = statbuf->st_size;
fstat_function_data.blocksize = statbuf->st_blksize;
fstat_function_data.allocated_512B_blocks = statbuf->st_blocks;
}

WRAP_END(data, fstat)
return ret;
}

int WRAP(fstat)(int fd, struct stat *statbuf)
{
int ret;
Expand Down Expand Up @@ -4125,6 +4209,47 @@ int WRAP(fstat)(int fd, struct stat *statbuf)
}

#ifdef HAVE_LSTAT
int WRAP(__lxstat)(const char *pathname, struct stat *statbuf)
{
int ret;
struct basic data;
struct stat_function stat_function_data;
WRAP_START(data)

get_basic(&data);
LIBIOTRACE_STRUCT_SET_VOID_P(data, function_data, stat_function,
stat_function_data)
POSIX_IO_SET_FUNCTION_NAME(data.function_name);
LIBIOTRACE_STRUCT_SET_VOID_P_NULL(data, file_type)
stat_function_data.file_name = pathname;

CALL_REAL_FUNCTION_RET(data, ret, lstat, pathname, statbuf)

if (-1 == ret)
{
data.return_state = error;
stat_function_data.type = unknown_stat_file_type;
stat_function_data.id.device_id = 0;
stat_function_data.id.inode_nr = 0;
stat_function_data.size = 0;
stat_function_data.blocksize = 0;
stat_function_data.allocated_512B_blocks = 0;
}
else
{
data.return_state = ok;
stat_function_data.type = get_stat_file_type(statbuf->st_mode);
stat_function_data.id.device_id = statbuf->st_dev;
stat_function_data.id.inode_nr = statbuf->st_ino;
stat_function_data.size = statbuf->st_size;
stat_function_data.blocksize = statbuf->st_blksize;
stat_function_data.allocated_512B_blocks = statbuf->st_blocks;
}

WRAP_END(data, lstat)
return ret;
}

int WRAP(lstat)(const char *pathname, struct stat *statbuf)
{
int ret;
Expand Down Expand Up @@ -4168,6 +4293,49 @@ int WRAP(lstat)(const char *pathname, struct stat *statbuf)
#endif

#ifdef HAVE_FSTATAT
int WRAP(__fxstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags)
{
int ret;
struct basic data;
struct fstatat_function fstatat_function_data;
WRAP_START(data)

get_basic(&data);
LIBIOTRACE_STRUCT_SET_VOID_P(data, function_data, fstatat_function,
fstatat_function_data)
POSIX_IO_SET_FUNCTION_NAME(data.function_name);
LIBIOTRACE_STRUCT_SET_VOID_P_NULL(data, file_type)
fstatat_function_data.file_name = pathname;
fstatat_function_data.file_descriptor = dirfd;
get_fstatat_flags(flags, &fstatat_function_data.flags);

CALL_REAL_FUNCTION_RET(data, ret, fstatat, dirfd, pathname, statbuf, flags)

if (-1 == ret)
{
data.return_state = error;
fstatat_function_data.type = unknown_stat_file_type;
fstatat_function_data.id.device_id = 0;
fstatat_function_data.id.inode_nr = 0;
fstatat_function_data.size = 0;
fstatat_function_data.blocksize = 0;
fstatat_function_data.allocated_512B_blocks = 0;
}
else
{
data.return_state = ok;
fstatat_function_data.type = get_stat_file_type(statbuf->st_mode);
fstatat_function_data.id.device_id = statbuf->st_dev;
fstatat_function_data.id.inode_nr = statbuf->st_ino;
fstatat_function_data.size = statbuf->st_size;
fstatat_function_data.blocksize = statbuf->st_blksize;
fstatat_function_data.allocated_512B_blocks = statbuf->st_blocks;
}

WRAP_END(data, fstatat)
return ret;
}

int WRAP(fstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags)
{
int ret;
Expand Down
6 changes: 6 additions & 0 deletions libiotrace/src/posix_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,19 @@ REAL_TYPE int REAL(recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vl
# endif
#endif

/* __xstat, __fxstat, __lxstat and __fxstatat needed for older glibc versions:
* stat, fstat, lstat and fstatat can be wrapping macros for the __*x* versions */
REAL_TYPE int REAL(stat)(const char *pathname, struct stat *statbuf) REAL_INIT;
REAL_TYPE int REAL(__xstat)(const char *pathname, struct stat *statbuf) REAL_INIT;
REAL_TYPE int REAL(fstat)(int fd, struct stat *statbuf) REAL_INIT;
REAL_TYPE int REAL(__fxstat)(int fd, struct stat *statbuf) REAL_INIT;
#ifdef HAVE_LSTAT
REAL_TYPE int REAL(lstat)(const char *pathname, struct stat *statbuf) REAL_INIT;
REAL_TYPE int REAL(__lxstat)(const char *pathname, struct stat *statbuf) REAL_INIT;
#endif
#ifdef HAVE_FSTATAT
REAL_TYPE int REAL(fstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags) REAL_INIT;
REAL_TYPE int REAL(__fxstatat)(int dirfd, const char *pathname, struct stat *statbuf, int flags) REAL_INIT;
#endif

//inotify_add_watch
Expand Down
4 changes: 4 additions & 0 deletions libiotrace/src/posix_io_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,16 @@ WRAPPER_NAME(sendmmsg)
#ifdef HAVE_RECVMMSG
WRAPPER_NAME(recvmmsg)
#endif
WRAPPER_NAME(__xstat)
WRAPPER_NAME(stat)
WRAPPER_NAME(__fxstat)
WRAPPER_NAME(fstat)
#ifdef HAVE_LSTAT
WRAPPER_NAME(__lxstat)
WRAPPER_NAME(lstat)
#endif
#ifdef HAVE_FSTATAT
WRAPPER_NAME(__fxstatat)
WRAPPER_NAME(fstatat)
#endif

Expand Down
4 changes: 4 additions & 0 deletions libiotrace/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ if (WITH_UNIT_TESTS)
"-Wl,-wrap=recvmsg"
"-Wl,-wrap=sendmmsg"
"-Wl,-wrap=recvmmsg"
"-Wl,-wrap=__xstat"
"-Wl,-wrap=__fxstat"
"-Wl,-wrap=__lxstat"
"-Wl,-wrap=__fxstatat"
"-Wl,-wrap=stat"
"-Wl,-wrap=fstat"
"-Wl,-wrap=lstat"
Expand Down
22 changes: 22 additions & 0 deletions libiotrace/test/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <dirent.h>

int main(void) {
struct stat sb;
Expand All @@ -23,8 +24,29 @@ int main(void) {

ret = fstatat(fd, "", &sb, AT_EMPTY_PATH);
assert(-1 != ret);

ret = fstatat(AT_FDCWD, "/etc/passwd", &sb, 0);
assert(-1 != ret);

DIR *dir = opendir("/etc");
assert(NULL != dir);

ret = fstatat(dirfd(dir), "./passwd", &sb, 0);
assert(-1 != ret);

ret = close (fd);

ret = stat("/etc/file_does_not_exist_at_all", &sb);
assert(-1 == ret);

ret = fstat(fd, &sb);
assert(-1 == ret);

ret = lstat("/etc/file_does_not_exist_at_all", &sb);
assert(-1 == ret);

ret = fstatat(fd, "", &sb, AT_EMPTY_PATH);
assert(-1 == ret);

return ret;
}

0 comments on commit 7004b7b

Please sign in to comment.