[FEATURE] File analysis: implement symlinks resolution 12/24112/2
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Tue, 8 Jul 2014 13:50:43 +0000 (17:50 +0400)
committerVasiliy Ulyanov <v.ulyanov@samsung.com>
Fri, 18 Jul 2014 09:37:39 +0000 (13:37 +0400)
Change-Id: I27d4991a4d0e81dc6fa7c0567b62ac14cef6ba48
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
helper/dahelper.c
include/dahelper.h
probe_file/da_io_posix.c
probe_file/da_io_stdc.c

index 4e70d5127291594d4c932f27c70cb738870c1177..040afe3e6228b876ffe681c12daae72d19ad8a0f 100755 (executable)
@@ -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;
 }
index e2b16b46199945046cd4fa7dd79d01931e93fec1..5a1f790578a1e2560fa56e14e66ef568bfe961ba 100755 (executable)
@@ -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();
index 79f7644e58112d6b488e421361779b7e3092c1b1..9d784358278664cc9befdc71dd00e4a987955190 100755 (executable)
 
 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;
 }
index a8be001889ebc12743003d9a072a4c7f46ecb00f..675f556c78c4589318bfb54961d18012e7e4adec 100644 (file)
 
 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;
 }