aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/hook_lib/file_hook.c')
-rw-r--r--src/hook_lib/file_hook.c149
1 files changed, 131 insertions, 18 deletions
diff --git a/src/hook_lib/file_hook.c b/src/hook_lib/file_hook.c
index 36e1328..7318149 100644
--- a/src/hook_lib/file_hook.c
+++ b/src/hook_lib/file_hook.c
@@ -56,11 +56,14 @@ int (*_readdir64_r)(DIR *dirp, struct dirent64 *entry,
int (*_access)(const char *pathname, int mode);
int (*_euidaccess)(const char *pathname, int mode);
+int (*_faccessat)(int dirfd, const char *pathname, int mode, int flags);
// these stat functions are only source level standart of glibc
// we no catch fxstat
int (*___xstat)(int vers, const char *name, struct stat *buf);
+int (*___xstat64)(int vers, const char *name, struct stat64 *buf);
int (*___lxstat)(int vers, const char *name, struct stat *buf);
+int (*___lxstat64)(int vers, const char *name, struct stat64 *buf);
int (*_execve)(const char *filename, char *const argv[],char *const envp[]);
int (*_execv)(const char *path, char *const argv[]);
@@ -165,10 +168,14 @@ void _init() {
_access=(int (*)(const char *pathname, int mode)) dlsym(RTLD_NEXT, "access");
_euidaccess=(int (*)(const char *pathname, int mode)) dlsym(RTLD_NEXT, "euidaccess");
-
+ _faccessat=(int(*)(int dirfd, const char *pathname, int mode, int flags)) dlsym(RTLD_NEXT, "faccessat");
+
+
___xstat=(int (*)(int vers, const char *name, struct stat *buf)) dlsym(RTLD_NEXT, "__xstat");
- ___lxstat=(int (*)(int vers, const char *name, struct stat *buf)) dlsym(RTLD_NEXT, "__lxstat");
-
+ ___xstat64=(int (*)(int vers, const char *name, struct stat64 *buf)) dlsym(RTLD_NEXT, "__xstat64");
+ ___lxstat=(int (*)(int vers, const char *name, struct stat *buf)) dlsym(RTLD_NEXT, "__lxstat");
+ ___lxstat64=(int (*)(int vers, const char *name, struct stat64 *buf)) dlsym(RTLD_NEXT, "__lxstat64");
+
_fork = (pid_t (*)()) dlsym(RTLD_NEXT, "fork");
_execve = (int (*)(const char *filename, char *const argv[],char *const envp[])) dlsym(RTLD_NEXT, "execve");
@@ -190,7 +197,7 @@ void _init() {
_read==NULL || _write==NULL || _mmap==NULL ||
_readdir==NULL || _readdir64 == NULL || _readdir_r==NULL ||
_readdir64_r==NULL ||
- _access==NULL || _euidaccess==NULL ||
+ _access==NULL || _euidaccess==NULL || _faccessat==NULL ||
_fork==NULL ||
_execve==NULL || _execv==NULL || _execvp==NULL || _execvpe==NULL ||
_fexecve==NULL || _system==NULL || _setenv==NULL || _close==NULL) {
@@ -271,6 +278,48 @@ ssize_t __get_path_by_fd(int fd, char *output, int output_len) {
}
/*
+ * Realpath. Resolved path is empty string on error. If path not exists,
+ * returns the path as is, but resolving current dir . Arguments must be not null
+*/
+char *myrealpath(const char *path, char *resolved){
+ char *ret=realpath(path,resolved);
+ if(ret!=NULL)
+ return ret;
+
+ if(path==NULL)
+ goto error;
+
+ // difficult case: error returned
+ char *dest;
+
+ if(path[0]!='/') {
+ if(! getcwd(resolved,MAXPATHLEN-2))
+ goto error;
+
+ dest= resolved+strlen(resolved);
+ dest[0]='/';
+ dest++;
+ dest[0]='\0';
+ } else {
+ dest = resolved;
+ }
+
+ char *border=resolved+MAXPATHLEN-1; // not crossing it and not stepping on it
+ if(dest>=border)
+ goto error;
+
+ strncpy(dest, path, border-dest);
+
+ return resolved;
+
+error:
+ resolved[0]=0;
+ return NULL;
+
+}
+
+
+/*
* Ask for event "alloweness"
*/
static int __is_event_allowed(const char *event_type,const char *filename, char* stage) {
@@ -337,7 +386,7 @@ void __fixenvp(char *const envp[], char *envp_new[]) {
int open(const char * path, int flags, mode_t mode) {
int ret;
char fullpath[MAXPATHLEN];
- realpath(path,fullpath);
+ myrealpath(path,fullpath);
char *stage=__get_stage();
if(! __is_event_allowed("open",fullpath,stage)) {
__log_event("open",fullpath,"DENIED",errno,stage);
@@ -360,7 +409,7 @@ int open(const char * path, int flags, mode_t mode) {
int open64(const char * path, int flags, mode_t mode) {
int ret;
char fullpath[MAXPATHLEN];
- realpath(path,fullpath);
+ myrealpath(path,fullpath);
char *stage=__get_stage();
if(! __is_event_allowed("open",fullpath,stage)) {
__log_event("open",path,"DENIED",errno,stage);
@@ -383,7 +432,7 @@ int open64(const char * path, int flags, mode_t mode) {
FILE *fopen(const char *path, const char *mode) {
FILE *ret;
char fullpath[MAXPATHLEN];
- realpath(path,fullpath);
+ myrealpath(path,fullpath);
char *stage=__get_stage();
if(! __is_event_allowed("open",fullpath,stage)) {
@@ -405,7 +454,7 @@ FILE *fopen(const char *path, const char *mode) {
FILE *fopen64(const char *path, const char *mode) {
FILE *ret;
char fullpath[MAXPATHLEN];
- realpath(path,fullpath);
+ myrealpath(path,fullpath);
char *stage=__get_stage();
if(! __is_event_allowed("open",fullpath,stage)) {
@@ -779,7 +828,7 @@ struct dirent *readdir(DIR *dirp) {
snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,ep->d_name);
char abspath[MAXPATHLEN];
- realpath(fullpath,abspath);
+ myrealpath(fullpath,abspath);
if(! __is_event_allowed("open",abspath,stage)) {
//__log_event("open",abspath,"DENIED",errno,stage);
@@ -809,7 +858,7 @@ struct dirent64 *readdir64(DIR *dirp) {
snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,ep->d_name);
char abspath[MAXPATHLEN];
- realpath(fullpath,abspath);
+ myrealpath(fullpath,abspath);
if(! __is_event_allowed("open",abspath,stage)) {
//__log_event("open",abspath,"DENIED",errno,stage);
@@ -845,7 +894,7 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result){
snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,entry->d_name);
char abspath[MAXPATHLEN];
- realpath(fullpath,abspath);
+ myrealpath(fullpath,abspath);
if(! __is_event_allowed("open",abspath,stage)) {
//__log_event("open",abspath,"DENIED",errno,stage);
@@ -881,7 +930,7 @@ int readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result){
snprintf(fullpath,MAXPATHLEN,"%s/%s",dirpath,entry->d_name);
char abspath[MAXPATHLEN];
- realpath(fullpath,abspath);
+ myrealpath(fullpath,abspath);
if(! __is_event_allowed("open",abspath,stage)) {
//__log_event("open",abspath,"DENIED",errno,stage);
@@ -899,10 +948,13 @@ int __xstat (int vers, const char *name, struct stat *buf) {
char *stage=__get_stage();
char fullpath[MAXPATHLEN];
- realpath(name,fullpath);
+ myrealpath(name,fullpath);
- if(! __is_event_allowed("open",fullpath,stage))
+ if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
+ errno=2;
return -1;
+ }
if(___xstat==NULL)
return -1;
@@ -910,14 +962,33 @@ int __xstat (int vers, const char *name, struct stat *buf) {
return ___xstat(vers,name,buf);
}
-int __lxstat (int vers, const char *name, struct stat *buf) {
+int __xstat64 (int vers, const char *name, struct stat64 *buf) {
char *stage=__get_stage();
char fullpath[MAXPATHLEN];
- realpath(name,fullpath);
+ myrealpath(name,fullpath);
+
+ if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
+ errno=2;
+ return -1;
+ }
+
+ if(___xstat64==NULL)
+ return -1;
+
+ return ___xstat64(vers,name,buf);
+}
+
+int __lxstat (int vers, const char *name, struct stat *buf) {
+ char *stage=__get_stage();
+
+ char fullpath[MAXPATHLEN];
+ myrealpath(name,fullpath);
if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
errno = 2;
return -1;
}
@@ -928,13 +999,33 @@ int __lxstat (int vers, const char *name, struct stat *buf) {
return ___lxstat(vers,name,buf);
}
+int __lxstat64 (int vers, const char *name, struct stat64 *buf) {
+ char *stage=__get_stage();
+
+ char fullpath[MAXPATHLEN];
+ myrealpath(name,fullpath);
+
+ if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
+ errno = 2;
+ return -1;
+ }
+
+ if(___lxstat64==NULL)
+ return -1;
+
+ return ___lxstat64(vers,name,buf);
+}
+
+
int access(const char *pathname, int mode) {
char *stage=__get_stage();
char fullpath[MAXPATHLEN];
- realpath(pathname,fullpath);
+ myrealpath(pathname,fullpath);
if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
errno = 2;
return -1;
}
@@ -946,9 +1037,10 @@ int euidaccess(const char *pathname, int mode) {
char *stage=__get_stage();
char fullpath[MAXPATHLEN];
- realpath(pathname,fullpath);
+ myrealpath(pathname,fullpath);
if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
errno = 2;
return -1;
}
@@ -956,6 +1048,27 @@ int euidaccess(const char *pathname, int mode) {
return _euidaccess(pathname,mode);
}
+int faccessat(int dirfd, const char *pathname, int mode, int flags){
+ char *stage=__get_stage();
+
+
+ char filepath[MAXPATHLEN];
+ char fullpath[MAXPATHLEN];
+ int len=__get_path_by_fd(dirfd,filepath,MAXPATHLEN);
+ if(len==-1)
+ filepath[0]=0;
+ strcat(filepath,"/");
+ strcat(filepath,pathname);
+ myrealpath(filepath,fullpath);
+
+ if(! __is_event_allowed("open",fullpath,stage)) {
+ __log_event("open",fullpath,"DENIED",errno,stage);
+ errno = 2;
+ return -1;
+ }
+
+ return _faccessat(dirfd,pathname,mode,flags);
+}
int setenv(const char *name, const char *value, int overwrite) {