diff options
author | Alexander Bersenev <bay@hackerdom.ru> | 2011-08-03 02:18:25 +0000 |
---|---|---|
committer | Alexander Bersenev <bay@hackerdom.ru> | 2011-08-03 02:18:25 +0000 |
commit | bd663fa24ca37b2ea697e782f6548e6133f8365f (patch) | |
tree | 502fba14cbb8017306a4a8d8099225d51a410363 /src | |
parent | auto access blocking (diff) | |
download | autodep-bd663fa24ca37b2ea697e782f6548e6133f8365f.tar.gz autodep-bd663fa24ca37b2ea697e782f6548e6133f8365f.tar.bz2 autodep-bd663fa24ca37b2ea697e782f6548e6133f8365f.zip |
hooklib: hide blocked files in directories
Diffstat (limited to 'src')
-rw-r--r-- | src/hook_lib/file_hook.c | 158 |
1 files changed, 156 insertions, 2 deletions
diff --git a/src/hook_lib/file_hook.c b/src/hook_lib/file_hook.c index 555d6dc..9f114ae 100644 --- a/src/hook_lib/file_hook.c +++ b/src/hook_lib/file_hook.c @@ -11,6 +11,8 @@ #include <dlfcn.h> #include <pthread.h> +#include <dirent.h> + #define _FCNTL_H #include <bits/fcntl.h> @@ -19,7 +21,7 @@ #include <sys/socket.h> #include <sys/un.h> -#define MAXPATHLEN 1024 +#define MAXPATHLEN PATH_MAX #define MAXSOCKETPATHLEN 108 #define MAXFILEBUFFLEN 2048 @@ -44,6 +46,13 @@ size_t (*_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); void *(*_mmap)(void *addr, size_t length, int prot, int flags, int fd, off_t offset); +struct dirent * (*_readdir)(DIR *dirp); +struct dirent64 * (*_readdir64)(DIR *dirp); +int (*_readdir_r)(DIR *dirp, struct dirent *entry, + struct dirent **result); +int (*_readdir64_r)(DIR *dirp, struct dirent64 *entry, + struct dirent64 **result); + int (*_execve)(const char *filename, char *const argv[],char *const envp[]); int (*_execv)(const char *path, char *const argv[]); @@ -139,6 +148,12 @@ void _init() { _mmap=(void* (*)(void *addr, size_t length, int prot, int flags, int fd, off_t offset)) dlsym(RTLD_NEXT, "mmap"); + _readdir=(struct dirent * (*)(DIR *dirp)) dlsym(RTLD_NEXT, "readdir"); + _readdir64=(struct dirent64 * (*)(DIR *dirp)) dlsym(RTLD_NEXT, "readdir64"); + _readdir_r=(int (*)(DIR *dirp, struct dirent *entry, + struct dirent **result)) dlsym(RTLD_NEXT, "readdir_r"); + _readdir64_r=(int (*)(DIR *dirp, struct dirent64 *entry, + struct dirent64 **result)) dlsym(RTLD_NEXT, "readdir64_r"); _fork = (pid_t (*)()) dlsym(RTLD_NEXT, "fork"); @@ -159,7 +174,9 @@ void _init() { if(_open==NULL || _open64==NULL || _fopen==NULL || _fopen64==NULL || - _read==NULL || _write==NULL || _mmap==NULL || + _read==NULL || _write==NULL || _mmap==NULL || + _readdir==NULL || _readdir64 == NULL || _readdir_r==NULL || + _readdir64_r==NULL || _fork==NULL || _execve==NULL || _execv==NULL || _execvp==NULL || _execvpe==NULL || _fexecve==NULL || _system==NULL || _setenv==NULL || _close==NULL) { @@ -727,6 +744,143 @@ void *mmap(void *addr, size_t length, int prot, int flags, return ret; } +// directory reading hooks +// the strategy for all functions is basic: skip the file if it is blocked +// all function are in two very similar variants: 32bit and 64bit +struct dirent *readdir(DIR *dirp) { + char *stage=__get_stage(); + struct dirent *ep; + + char dirpath[MAXPATHLEN]; + + int fd; + fd=dirfd(dirp); + + // get dirname in dirpath + if (__get_path_by_fd(fd,dirpath,MAXPATHLEN)==-1) + return _readdir(dirp); + + while((ep=_readdir(dirp))!=NULL) { // Hope that readdir is not looping + char fullpath[MAXPATHLEN]; + snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,ep->d_name); + + char abspath[MAXPATHLEN]; + realpath(fullpath,abspath); + + if(! __is_event_allowed("open",abspath,stage)) { + __log_event("open",abspath,"DENIED",errno,stage); + + continue; + } else + break; + } + return ep; +} + +struct dirent64 *readdir64(DIR *dirp) { + char *stage=__get_stage(); + struct dirent64 *ep; + + char dirpath[MAXPATHLEN]; + + int fd; + fd=dirfd(dirp); + + // get dirname in dirpath + if (__get_path_by_fd(fd,dirpath,MAXPATHLEN)==-1) + return _readdir64(dirp); + + while((ep=_readdir64(dirp))!=NULL) { // Hope that readdir is not looping + char fullpath[MAXPATHLEN]; + snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,ep->d_name); + + char abspath[MAXPATHLEN]; + realpath(fullpath,abspath); + + if(! __is_event_allowed("open",abspath,stage)) { + __log_event("open",abspath,"DENIED",errno,stage); + + continue; + } else + break; + } + return ep; +} + + +// next two functions are almost equal +int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result){ + char *stage=__get_stage(); + char dirpath[MAXPATHLEN]; + + int fd; + fd=dirfd(dirp); + + // get dirname in dirpath + if (__get_path_by_fd(fd,dirpath,MAXPATHLEN)==-1) + return _readdir_r(dirp, entry, result); + + int ret; + + while((ret=_readdir_r(dirp, entry, result))==0) { + if(*result==NULL) { + break; // end of directory + } + + char fullpath[MAXPATHLEN]; + snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,entry->d_name); + + char abspath[MAXPATHLEN]; + realpath(fullpath,abspath); + + if(! __is_event_allowed("open",abspath,stage)) { + __log_event("open",abspath,"DENIED",errno,stage); + + continue; + } else + break; + } + + return ret; +} + + +int readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result){ + char *stage=__get_stage(); + char dirpath[MAXPATHLEN]; + + int fd; + fd=dirfd(dirp); + + // get dirname in dirpath + if (__get_path_by_fd(fd,dirpath,MAXPATHLEN)==-1) + return _readdir64_r(dirp, entry, result); + + int ret; + + while((ret=_readdir64_r(dirp, entry, result))==0) { + if(*result==NULL) { + break; // end of directory + } + + char fullpath[MAXPATHLEN]; + snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,entry->d_name); + + char abspath[MAXPATHLEN]; + realpath(fullpath,abspath); + + if(! __is_event_allowed("open",abspath,stage)) { + __log_event("open",abspath,"DENIED",errno,stage); + + continue; + } else + break; + } + + return ret; +} + + int setenv(const char *name, const char *value, int overwrite) { //printf (" CHANGING name: %s, value: %s",name,value); if(strcmp(name,"LD_PRELOAD")==0 || |