From 55fae785a359cfa3a2075ca65aa0e4f6d400ee56 Mon Sep 17 00:00:00 2001 From: Vasiliy Ulyanov Date: Tue, 8 Jul 2014 17:50:43 +0400 Subject: [PATCH] [FEATURE] File analysis: implement symlinks resolution Change-Id: I27d4991a4d0e81dc6fa7c0567b62ac14cef6ba48 Signed-off-by: Vasiliy Ulyanov --- helper/dahelper.c | 26 ++++++++++++++++++++++---- include/dahelper.h | 5 ++++- probe_file/da_io_posix.c | 28 ++++++++++++++++++++-------- probe_file/da_io_stdc.c | 23 ++++++++++++++++++----- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/helper/dahelper.c b/helper/dahelper.c index 4e70d51..040afe3 100755 --- a/helper/dahelper.c +++ b/helper/dahelper.c @@ -121,15 +121,33 @@ static int absolute_filepath_p(const char *fname) return fname[0] == '/'; } -/* Return pointer to static buffer */ -char *absolutize_filepath(char buffer[PATH_MAX], const char *fname) +char *absolutize_filepath(const char *fname, char *buffer, size_t bufsiz) { char cwd[PATH_MAX]; assert(fname && "Filename, passed to stdc function is NULL."); if (absolute_filepath_p(fname) || getcwd(cwd, sizeof(cwd)) == NULL) - snprintf(buffer, PATH_MAX, "%s", fname); + snprintf(buffer, bufsiz, "%s", fname); else - snprintf(buffer, PATH_MAX, "%s/%s", cwd, fname); + snprintf(buffer, bufsiz, "%s/%s", cwd, fname); + return buffer; +} + +char *real_abs_path(int fd, char *buffer, size_t bufsiz) +{ + static const char *PROC_FD = "/proc/self/fd/%d"; + char proc_path[sizeof(PROC_FD) + 16]; /* PATH_MAX not needed here */ + ssize_t ret = 0; + + if (fd < 0) + return NULL; + + sprintf(proc_path, PROC_FD, fd); + + ret = readlink(proc_path, buffer, bufsiz); + if (ret < 0) /* some error occured */ + return NULL; + buffer[ret] = '\0'; + return buffer; } diff --git a/include/dahelper.h b/include/dahelper.h index e2b16b4..5a1f790 100755 --- a/include/dahelper.h +++ b/include/dahelper.h @@ -219,7 +219,10 @@ int __profil(int mode); //wchar_t* -> char* void WcharToChar(char* pstrDest, const wchar_t* pwstrSrc); -char *absolutize_filepath(char buf[PATH_MAX], const char *fname); +char *absolutize_filepath(const char *fname, char *buf, size_t bufsiz); + +/* returns the real absolute file path (resolves symlinks) */ +char *real_abs_path(int fd, char *buffer, size_t bufsiz); // screen capture functions int initialize_screencapture(); diff --git a/probe_file/da_io_posix.c b/probe_file/da_io_posix.c index 79f7644..9d78435 100755 --- a/probe_file/da_io_posix.c +++ b/probe_file/da_io_posix.c @@ -54,6 +54,17 @@ static enum DaOptions _sopt = OPT_FILE; +static inline char *get_abs_path(int fd, const char *fname, + char *buf, size_t bufsiz) +{ + char *path = real_abs_path(fd, buf, bufsiz); + + if (!path) + path = absolutize_filepath(fname, buf, bufsiz); + + return path; +} + int open(const char* path, int oflag, ...) { static int (*openp)(const char* path, int oflag, ...); @@ -61,7 +72,6 @@ int open(const char* path, int oflag, ...) int mode = 0; BEFORE_ORIGINAL_FILE_NOFILTER(open, LIBC); - _filepath = (char*)path; if(oflag & O_CREAT) { @@ -73,9 +83,10 @@ int open(const char* path, int oflag, ...) ret = openp(path, oflag, mode); + _filepath = get_abs_path(ret, path, buffer, PATH_MAX); + AFTER_PACK_ORIGINAL_FD(API_ID_open, 'd', ret, 0, ret, FD_API_OPEN, - "s4dd", absolutize_filepath(buffer, path), oflag, - mode); + "s4dd", path, oflag, mode); return ret; } @@ -87,7 +98,6 @@ int openat(int fd, const char* path, int oflag, ...) int mode = 0; BEFORE_ORIGINAL_FILE_NOFILTER(openat, LIBC); - _filepath = (char*)path; if(oflag & O_CREAT) { @@ -99,9 +109,10 @@ int openat(int fd, const char* path, int oflag, ...) ret = openatp(fd, path, oflag, mode); + _filepath = get_abs_path(ret, path, buffer, PATH_MAX); + AFTER_PACK_ORIGINAL_FD(API_ID_openat, 'd', ret, 0, ret, FD_API_OPEN, - "ds4dd", fd, absolutize_filepath(buffer, path), - oflag, mode); + "ds4dd", fd, path, oflag, mode); return ret; } @@ -112,12 +123,13 @@ int creat(const char* path, mode_t mode) char buffer[PATH_MAX]; BEFORE_ORIGINAL_FILE_NOFILTER(creat, LIBC); - _filepath = (char*)path; ret = creatp(path, mode); + _filepath = get_abs_path(ret, path, buffer, PATH_MAX); + AFTER_PACK_ORIGINAL_FD(API_ID_creat, 'd', ret, 0, ret, FD_API_OPEN, - "s4d", absolutize_filepath(buffer, path), mode); + "s4d", path, mode); return ret; } diff --git a/probe_file/da_io_stdc.c b/probe_file/da_io_stdc.c index a8be001..675f556 100644 --- a/probe_file/da_io_stdc.c +++ b/probe_file/da_io_stdc.c @@ -46,6 +46,17 @@ static enum DaOptions _sopt = OPT_FILE; +static inline char *get_abs_path(FILE *file, const char *fname, + char *buf, size_t bufsiz) +{ + char *path = file ? real_abs_path(fileno(file), buf, bufsiz): NULL; + + if (!path) + path = absolutize_filepath(fname, buf, bufsiz); + + return path; +} + FILE* fopen(const char* filename, const char* mode) { static FILE* (*fopenp)(const char* filename, const char* mode); @@ -53,13 +64,14 @@ FILE* fopen(const char* filename, const char* mode) FILE* fret; BEFORE_ORIGINAL_FILE_NOFILTER(fopen, LIBC); - _filepath = (char*)filename; fret = fopenp(filename, mode); + _filepath = get_abs_path(fret, filename, buffer, PATH_MAX); + AFTER_PACK_ORIGINAL_FILEP(API_ID_fopen, 'p', fret, 0, fret, FD_API_OPEN, "s4s", - absolutize_filepath(buffer, filename), mode); + filename, mode); return fret; } @@ -72,13 +84,14 @@ FILE* freopen(const char * filename, const char * mode, FILE * stream) FILE* fret; BEFORE_ORIGINAL_FILE_NOFILTER(freopen, LIBC); - _filepath = (char*)filename; fret = freopenp(filename, mode, stream); + _filepath = get_abs_path(fret, filename, buffer, PATH_MAX); + AFTER_PACK_ORIGINAL_FILEP(API_ID_freopen, 'p', fret, 0, fret, FD_API_OPEN, - "s4sp", absolutize_filepath(buffer, filename), - mode, voidp_to_uint64(stream)); + "s4sp", filename, mode, + voidp_to_uint64(stream)); return fret; } -- 2.7.4