diff options
author | Alexander Bersenev <bay@hackerdom.ru> | 2011-07-06 23:44:26 +0000 |
---|---|---|
committer | Alexander Bersenev <bay@hackerdom.ru> | 2011-07-06 23:44:26 +0000 |
commit | eb64287c7e19a3b5671dc3b45c092722739b3b65 (patch) | |
tree | 5f764a51d4969943d630d0280bcecdb82d417183 | |
parent | work with usersandbox feature, futher work for outout (diff) | |
download | autodep-eb64287c7e19a3b5671dc3b45c092722739b3b65.tar.gz autodep-eb64287c7e19a3b5671dc3b45c092722739b3b65.tar.bz2 autodep-eb64287c7e19a3b5671dc3b45c092722739b3b65.zip |
many new calls hooked, internal structures format was vhanged
-rw-r--r-- | NOTES | 22 | ||||
-rwxr-xr-x | logger/src/autodep/showfsevents.py | 140 | ||||
-rw-r--r-- | logger/src/hook_lib/file_hook.c | 337 |
3 files changed, 324 insertions, 175 deletions
@@ -13,17 +13,17 @@ This is few notes mainly for myself. 3. Format of events structure: [ { - <stage of building>:{<filename>:[<was readed>,<was writed>]} + <stage of building>:{<filename>:(<was readed>,<was writed>)} }, { - <stage of building>:{<filename>:[<was not found>,<was blocked>]} + <stage of building>:{<filename>:(<was not found>,<was blocked>)} } ] 4. Format of converted events structure: { - packagesinfo: { - <package>: { +# packagesinfo: { + <package|unknown>: { stage: { <filename>: {found:[<was readed>,<was writed>], @@ -32,12 +32,12 @@ This is few notes mainly for myself. } } - otherfilesinfo: { - stage:{ - <filename>: - {found:[<was readed>,<was writed>], - notfound:[<was not found>,<was blocked>]} - } - } + #otherfilesinfo: { + # stage:{ + # <filename>: + # {found:[<was readed>,<was writed>], + # notfound:[<was not found>,<was blocked>]} + #} + #} } diff --git a/logger/src/autodep/showfsevents.py b/logger/src/autodep/showfsevents.py index b738a76..68f8425 100755 --- a/logger/src/autodep/showfsevents.py +++ b/logger/src/autodep/showfsevents.py @@ -11,10 +11,13 @@ import logfs.portage_utils args_parser=optparse.OptionParser("%prog [options] <command>") args_parser.add_option("-b", "--block",action="store", type="string", dest="packages", default="", help="block an access to files from this packages") +args_parser.add_option("-u", "--unknown", action="store_true", dest="show_unknown", + default=False, help="show unknown stage and files from unknown package") args_parser.add_option("-v", action="store_true", dest="verbose", default=False, help="show accessed files") -args_parser.add_option("-u", "--unknown", action="store_true", dest="show_unknown_stage", - default=False, help="show unknown stage") +args_parser.add_option("-n","--notfound", action="store_true", dest="show_notfound", + default=False, help="show not founded files") + args_parser.add_option("--hooklib",action="store_const", dest="approach", const="hooklib", help="use ld_preload logging approach(default)") @@ -73,12 +76,13 @@ file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) # this part is completly unreadable. It converting one complex struct(returned by getfsevents) to # another complex struct which good for generating output +# old struct is also used during output -events_converted_for_output={} +#events_converted_for_output={} packagesinfo={} -events_converted_for_output["packagesinfo"]=packagesinfo -otherfilesinfo={} -events_converted_for_output["otherfilesinfo"]=otherfilesinfo +#events_converted_for_output=packagesinfo +#otherfilesinfo={} +#events_converted_for_output["otherfilesinfo"]=otherfilesinfo for stage in sorted(events): succ_events=events[stage][0] @@ -87,15 +91,18 @@ for stage in sorted(events): for filename in succ_events: if filename in file_to_package: package=file_to_package[filename] - if not package in packagesinfo: - packagesinfo[package]={} - stageinfo=packagesinfo[package] - if not stage in stageinfo: - stageinfo[stage]={} else: - stageinfo=otherfilesinfo - if not stage in stageinfo: - stageinfo[stage]={} + package="unknown" + + if not package in packagesinfo: + packagesinfo[package]={} + stageinfo=packagesinfo[package] + if not stage in stageinfo: + stageinfo[stage]={} +# else: +# stageinfo=otherfilesinfo +# if not stage in stageinfo: +# stageinfo[stage]={} filesinfo=stageinfo[stage] if not filename in filesinfo: @@ -105,15 +112,17 @@ for stage in sorted(events): for filename in fail_events: if filename in file_to_package: package=file_to_package[filename] - if not package in packagesinfo: - packagesinfo[package]={} - stageinfo=packagesinfo[package] - if not stage in stageinfo: - stageinfo[stage]={} else: - stageinfo=otherfilesinfo - if not stage in stageinfo: - stageinfo[stage]={} + package="unknown" + if not package in packagesinfo: + packagesinfo[package]={} + stageinfo=packagesinfo[package] + if not stage in stageinfo: + stageinfo[stage]={} + #else: + # stageinfo=otherfilesinfo + # if not stage in stageinfo: + # stageinfo[stage]={} filesinfo=stageinfo[stage] if not filename in filesinfo: @@ -133,15 +142,18 @@ for package in packagesinfo: stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7, "install":8,"preinst":9,"postinst":10,"prerm":11,"postrm":12,"unknown":13} - +# print information grouped by package for package in sorted(packagesinfo): # not showing special directory package if package=="directory": continue + if package=="unknown" and not options.show_unknown: + continue + stages=[] for stage in sorted(packagesinfo[package].keys(), key=stagesorder.get): - if stage!="unknown" or options.show_unknown_stage or not was_emerge_process: + if stage!="unknown" or options.show_unknown or not was_emerge_process: stages.append(stage) if len(stages)!=0: @@ -158,56 +170,36 @@ for package in sorted(packagesinfo): else: old_was_readed, old_was_writed=filenames[filename] filenames[filename]=[old_was_readed | was_readed, old_was_writed | was_writed ] - + + # this is here for readability + action={ + (False,False):"accessed", + (True,False):"readed", + (False,True):"writed", + (True,True):"readed and writed" + } + for filename in filenames: - if filenames[filename]==[False,False]: - action="accessed" - elif filenames[filename]==[True,False]: - action="readed" - elif filenames[filename]==[False,True]: - action="writed" - elif filenames[filename]==[True,True]: - action="readed and writed" - print " %-56s %-21s" % (filename,action) - + event_info=tuple(filenames[filename]) + print " %-56s %-21s" % (filename,action[event_info]) + +# print not founded files with stages +if options.show_notfound: + filenames={} + print "\nNot founded files:" + for stage in sorted(events, key=stagesorder.get): + print "%s:" % stage - -""" -for stage in sorted(events, key=stagesorder.get): - succ_events=events[stage][0] - fail_events=events[stage][1] - print "On stage %s:" % stage - for filename in sorted(succ_events, key=file_to_package.get): - print " %-40s" % filename, - action="" - if succ_events[filename]==[False,False]: - action="accessed", - elif succ_events[filename]==[True,False]: - action="readed", - elif succ_events[filename]==[False,True]: - action="writed", - elif succ_events[filename]==[True,True]: - action="readed and writed", - - print " %-21s " % action, - if filename in file_to_package: - print file_to_package[filename], - print + action={ + (True,False):"file not found", + (True,True):"blocked and not found", + (False,True):"blocked", + (False,False):"other error" + } + + fail_events=events[stage][1] - for filename in sorted(fail_events, key=file_to_package.get): - print " %-40s" % filename, - action="" - if fail_events[filename]==[True,False]: - action="file not found" - elif fail_events[filename]==[True,True]: - action="blocked and not found" - elif fail_events[filename]==[False,True]: - action="blocked" - elif fail_events[filename]==[False,False]: - action="other error" - print " %-21s " % action, - if filename in file_to_package: - print file_to_package[filename], - print - """ -##logfs.fstracer.getfsevents("emerge", ["emerge","--info"]) + for filename in sorted(fail_events, key=file_to_package.get): + reason=tuple(fail_events[filename]) + print " %-56s %-21s" % (filename,action[reason]) + diff --git a/logger/src/hook_lib/file_hook.c b/logger/src/hook_lib/file_hook.c index 9012b20..efe3c9c 100644 --- a/logger/src/hook_lib/file_hook.c +++ b/logger/src/hook_lib/file_hook.c @@ -2,6 +2,7 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <unistd.h> #include <errno.h> #include <string.h> @@ -25,6 +26,7 @@ #define MAXENVSIZE 65536 #define MAXENVITEMSIZE 256 +#define MAXARGS 256 //extern int errorno; pthread_mutex_t socketblock = PTHREAD_MUTEX_INITIALIZER; @@ -41,8 +43,13 @@ size_t (*_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); int (*_execve)(const char *filename, char *const argv[],char *const envp[]); int (*_execv)(const char *path, char *const argv[]); int (*_execvp)(const char *file, char *const argv[]); +int (*_execvpe)(const char *file, char *const argv[], char *const envp[]); + +//int (*_execl)(const char *path, const char *arg, ...); int (*_fexecve)(int fd, char *const argv[], char *const envp[]); + + int (*_system)(const char *command); pid_t (*_fork)(); @@ -52,8 +59,11 @@ int (*_close)(int fd); // we hooking this, because some programs closes our sock int log_socket=-1; -char log_socket_name[MAXSOCKETPATHLEN]; char ld_preload_orig[MAXPATHLEN]; +char log_socket_name[MAXSOCKETPATHLEN]; + +char ld_preload_env[MAXENVITEMSIZE]; // value: LD_PRELOAD=ld_preload_orig +char log_socket_env[MAXENVITEMSIZE]; // value: LOG_SOCKET=log_socket_name void __doconnect(){ if(strlen(log_socket_name)>=MAXSOCKETPATHLEN) { @@ -126,9 +136,13 @@ void _init() { _write= (ssize_t (*)(int fd, const void *buf, size_t count)) dlsym(RTLD_NEXT, "write"); _fork = (pid_t (*)()) dlsym(RTLD_NEXT, "fork"); + _execve = (int (*)(const char *filename, char *const argv[],char *const envp[])) dlsym(RTLD_NEXT, "execve"); _execv = (int (*)(const char *path, char *const argv[])) dlsym(RTLD_NEXT, "execv"); _execvp = (int (*)(const char *file, char *const argv[])) dlsym(RTLD_NEXT, "execvp"); + _execvpe = (int (*)(const char *file, char *const argv[], char *const envp[])) dlsym(RTLD_NEXT, "execvpe"); + + //_execl =(int (*)(const char *path, const char *arg, ...)) dlsym(RTLD_NEXT, "execl"); _fexecve = (int (*)(int fd, char *const argv[], char *const envp[])) dlsym(RTLD_NEXT, "fexecve"); @@ -142,12 +156,17 @@ void _init() { if(_open==NULL || _open64==NULL || _fopen==NULL || _fopen64==NULL || _read==NULL || _write==NULL || - _fork==NULL || _execve==NULL || _execv==NULL || _fexecve==NULL || _execvp==NULL || - _system==NULL || _setenv==NULL || _close==NULL) { + _fork==NULL || + _execve==NULL || _execv==NULL || _execvp==NULL || _execvpe==NULL || + _fexecve==NULL || _system==NULL || _setenv==NULL || _close==NULL) { fprintf(stderr,"Failed to load original functions of hook\n"); exit(1); } + snprintf(ld_preload_env,MAXENVITEMSIZE,"LD_PRELOAD=%s",ld_preload_orig); + snprintf(log_socket_env,MAXENVITEMSIZE,"LOG_SOCKET=%s",log_socket_name); + + __doconnect(); } @@ -250,6 +269,59 @@ static int __is_event_allowed(const char *event_type,const char *filename, char* } + +void __fixenv() { + _setenv("LOG_SOCKET",log_socket_name,1); + _setenv("LD_PRELOAD",ld_preload_orig,1); + snprintf(ld_preload_env,MAXENVITEMSIZE,"LD_PRELOAD=%s",ld_preload_orig); + snprintf(log_socket_env,MAXENVITEMSIZE,"LOG_SOCKET=%s",log_socket_name); +} + +/* + * Fixes LD_PRELOAD and LOG_SOCKET in envp and puts modified value in envp_new +*/ +void __fixenvp(char *const envp[], char *envp_new[]) { + int ld_preload_valid=0; + int log_socket_valid=0; + int i; + for(i=0;envp[i];i++){ + if(strncmp(envp[i],"LD_PRELOAD=",11)==0) + if(strcmp(envp[i]+11,ld_preload_orig)==0) + ld_preload_valid=1; + if(strncmp(envp[i],"LOG_SOCKET=",11)==0) + if(strcmp(envp[i]+11,log_socket_name)==0) + log_socket_valid=1; + } + if(!ld_preload_valid || !log_socket_valid) { + for(i=0; envp[i] && i<MAXENVSIZE-3; i++) { + if(strncmp(envp[i],"LD_PRELOAD=",11)==0) { + envp_new[i]=ld_preload_env; + ld_preload_valid=1; + } else if(strncmp(envp[i],"LOG_SOCKET=",11)==0) { + envp_new[i]=log_socket_env; + log_socket_valid=1; + } else { + envp_new[i]=envp[i]; + } + } + + if(!ld_preload_valid) { + envp_new[i]=ld_preload_env; + i++; + } + if(!log_socket_valid) { + envp_new[i]=log_socket_env; + i++; + } + envp_new[i]=NULL; + } +} + +/* + * Below are functions we hooking + * The common strategy is: + * 1) ask python part for allowness 2) do call 3) tell a result +*/ int open(const char * path, int flags, mode_t mode) { int ret; char fullpath[MAXPATHLEN]; @@ -356,8 +428,6 @@ ssize_t read(int fd, void *buf, size_t count){ __log_event("read",fullpath,"OK",0,stage); } - //__log_event("debug",fullpath,"ERR",getpid(),stage); - errno=saved_errno; return ret; } @@ -380,13 +450,8 @@ ssize_t write(int fd,const void *buf, size_t count){ } pid_t fork(void) { - //fprintf(stderr,"prefork %s %s\n",getenv("LOG_SOCKET"),log_socket_orig); - //int succ= - _setenv("LOG_SOCKET",log_socket_name,1); - _setenv("LD_PRELOAD",ld_preload_orig,1); - //ld_preload_orig - //fprintf(stderr,"prefork %s%p%p%d %s\n",getenv("LOG_SOCKET"),_setenv,setenv,succ,log_socket_orig); + __fixenv(); int ret=_fork(); int saved_errno=errno; @@ -405,77 +470,196 @@ pid_t fork(void) { int execve(const char *filename, char *const argv[], char *const envp[]) { + char *stage=__get_stage(); + if(! __is_event_allowed("open",filename,stage)) { + __log_event("open",filename,"DENIED",errno,stage); + errno=2; // not found + return -1; + } + if(access(filename, F_OK)!=-1) - __log_event("read",filename,"OK",0,__get_stage()); + __log_event("read",filename,"OK",0,stage); else - __log_event("open",filename,"ERR",2,__get_stage()); + __log_event("open",filename,"ERR",2,stage); - //fprintf(stderr,"executing %s pid=%d", filename,getpid()); - char *new_envp[MAXENVSIZE]; - char new_ld_preload[MAXENVITEMSIZE]; - char new_log_socket[MAXENVITEMSIZE]; + char *envp_new[MAXENVSIZE]; + __fixenvp(envp,envp_new); + + int ret=_execve(filename, argv, envp_new); - int ld_preload_valid=0; - int log_socket_valid=0; - int i; - for(i=0;envp[i];i++){ - if(strncmp(envp[i],"LD_PRELOAD=",11)==0) - if(strcmp(envp[i]+11,ld_preload_orig)==0) - ld_preload_valid=1; - if(strncmp(envp[i],"LOG_SOCKET=",11)==0) - if(strcmp(envp[i]+11,log_socket_name)==0) - log_socket_valid=1; + return ret; +} + +int execv(const char *path, char *const argv[]){ + char *stage=__get_stage(); + if(! __is_event_allowed("open",path,stage)) { + __log_event("open",path,"DENIED",errno,stage); + errno=2; // not found + return -1; } - if(!ld_preload_valid || !log_socket_valid) { - snprintf(new_ld_preload,MAXENVITEMSIZE,"LD_PRELOAD=%s",ld_preload_orig); - snprintf(new_log_socket,MAXENVITEMSIZE,"LOG_SOCKET=%s",log_socket_name); - for(i=0; envp[i] && i<MAXENVSIZE-3; i++) { - if(strncmp(envp[i],"LD_PRELOAD=",11)==0) { - new_envp[i]=new_ld_preload; - ld_preload_valid=1; - } else if(strncmp(envp[i],"LOG_SOCKET=",11)==0) { - new_envp[i]=new_log_socket; - log_socket_valid=1; - } else { - new_envp[i]=envp[i]; - } + + __fixenv(); + + if(access(path, F_OK)!=-1) + __log_event("read",path,"OK",0,stage); + else + __log_event("open",path,"ERR",2,stage); + + return _execv(path,argv); +} + +int execvp(const char *file, char *const argv[]){ + char *stage=__get_stage(); + if(strchr(file,'/')!=NULL) { + if(! __is_event_allowed("open",file,stage)) { + __log_event("open",file,"DENIED",errno,stage); + errno=2; // not found + return -1; } + + if(access(file, F_OK)!=-1) + __log_event("read",file,"OK",0,stage); + else + __log_event("open",file,"ERR",2,stage); + + } else { + // TODO: may me repeat bash's PATH parsing logic here + } - if(!ld_preload_valid) { - new_envp[i]=new_ld_preload; - i++; + __fixenv(); + + + return _execvp(file,argv); +} + +int execvpe(const char *file, char *const argv[], + char *const envp[]){ + char *stage=__get_stage(); + + if(strchr(file,'/')!=NULL) { + if(! __is_event_allowed("open",file,stage)) { + __log_event("open",file,"DENIED",errno,stage); + errno=2; // not found + return -1; } - if(!log_socket_valid) { - new_envp[i]=new_log_socket; - i++; -} - new_envp[i]=NULL; - envp=new_envp; -// for(i=0;envp[i];i++){ -// printf("BAY: %s\n",envp[i]); -// } + + if(access(file, F_OK)!=-1) + __log_event("read",file,"OK",0,stage); + else + __log_event("open",file,"ERR",2,stage); + + } else { + // TODO: may me repeat bash's PATH parsing logic here + } + + char *envp_new[MAXENVSIZE]; + __fixenvp(envp,envp_new); + + return _execvpe(file,argv,envp_new); +} +int execl(const char *path, const char *arg, ...){ + char *stage=__get_stage(); + if(! __is_event_allowed("open",path,stage)) { + __log_event("open",path,"DENIED",errno,stage); + errno=2; // not found + return -1; } + + __fixenv(); + + if(access(path, F_OK)!=-1) + __log_event("read",path,"OK",0,stage); + else + __log_event("open",path,"ERR",2,stage); - fflush(stderr); - int ret=_execve(filename, argv, envp); + va_list ap; + char * argv[MAXARGS+1]; + int i=0; - return ret; + va_start(ap,arg); + while(arg!=0 && i<MAXARGS) { + argv[i++]=arg; + arg=va_arg(ap,const char *); + } + argv[i]=NULL; + va_end(ap); + return _execv(path,argv); } -//int clone(int (*fn)(void *), void *child_stack, -// int flags, void *arg, ...) { -// fprintf(stderr,"clone pid=%d",getpid()); -// fflush(stderr); +int execlp(const char *file, const char *arg, ...) { + char *stage=__get_stage(); + if(strchr(file,'/')!=NULL) { + if(! __is_event_allowed("open",file,stage)) { + __log_event("open",file,"DENIED",errno,stage); + errno=2; // not found + return -1; + } + if(access(file, F_OK)!=-1) + __log_event("read",file,"OK",0,stage); + else + __log_event("open",file,"ERR",2,stage); + } else { + // TODO: may me repeat bash's PATH parsing logic here + } -// return -1;//_clone(fn,child_stack,flags,arg); -//} + __fixenv(); + + va_list ap; + char * argv[MAXARGS+1]; + int i=0; + + va_start(ap,arg); + while(arg!=0 && i<MAXARGS) { + argv[i++]=arg; + arg=va_arg(ap,const char *); + } + argv[i]=NULL; + va_end(ap); + return _execvp(file,argv); +} -/*int fexecve(int fd, char *const argv[], char *const envp[]) { +int execle(const char *path, const char *arg, ... ){ + char *stage=__get_stage(); + if(! __is_event_allowed("open",path,stage)) { + __log_event("open",path,"DENIED",errno,stage); + errno=2; // not found + return -1; + } + + if(access(path, F_OK)!=-1) + __log_event("read",path,"OK",0,stage); + else + __log_event("open",path,"ERR",2,stage); + + va_list ap; + char * argv[MAXARGS+1]; + argv[0]=arg; + + va_start(ap,arg); + int i=0; + while(argv[i++]!=NULL && i<MAXARGS) { + argv[i]=va_arg(ap,const char *); + } + char *const *envp=va_arg(ap, const char *const *); + + char *envp_new[MAXENVSIZE]; + __fixenvp(envp,envp_new); + + va_end(ap); + return _execve(path,argv,envp_new); +} + + + +/* +int fexecve(int fd, char *const argv[], char *const envp[]) { fprintf(stderr,"fexecuting pid=%d",getpid()); fflush(stderr); - return _fexecve(fd,argv,envp); + + int ret=_fexecve(fd, argv, envp); + return ret; } int execle(const char *path, const char *arg, ...) { @@ -485,38 +669,11 @@ int execle(const char *path, const char *arg, ...) { return 0; } -int execl(const char *path, const char *arg, ...){ - fprintf(stderr,"execluting 1 pid=%d",getpid()); - fflush(stderr); -// - return 0; -} -int execv(const char *path, char *const argv[]){ - fprintf(stderr,"execvuting 1 pid=%d",getpid()); - fflush(stderr); - _execv(path,argv); - return 0; -} -int execvp(const char *file, char *const argv[]){ - fprintf(stderr,"execvpting 1 pid=%d",getpid()); - fflush(stderr); - return _execvp(file,argv); - - return 0; -} -int execvpe(const char *file, char *const argv[], - char *const envp[]){ - fprintf(stderr,"execvpeting 1 pid=%d",getpid()); - fflush(stderr); -// - return 0; -} - int execlp(const char *file, const char *arg, ...){ fprintf(stderr,"execlpeting 1 pid=%d",getpid()); fflush(stderr); |