aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bersenev <bay@hackerdom.ru>2011-08-21 14:26:52 +0000
committerAlexander Bersenev <bay@hackerdom.ru>2011-08-21 14:26:52 +0000
commitfdbe127317c8f8df356d6f772c613557243fcc63 (patch)
tree46033c358c9cb4d5362ef051a2fdd97af298a5ea
parentdocumentation fixes (diff)
downloadautodep-fdbe127317c8f8df356d6f772c613557243fcc63.tar.gz
autodep-fdbe127317c8f8df356d6f772c613557243fcc63.tar.bz2
autodep-fdbe127317c8f8df356d6f772c613557243fcc63.zip
big code commit in the last day before pencils down date
-rwxr-xr-xsrc/autodep/autodep87
-rw-r--r--src/autodep/helpers/events_analysis.py1
-rw-r--r--src/autodep/logfs/fstracer.py10
-rw-r--r--src/autodep/package_utils/portage_misc_functions.py41
-rw-r--r--src/hook_lib/file_hook.c149
5 files changed, 236 insertions, 52 deletions
diff --git a/src/autodep/autodep b/src/autodep/autodep
index f202d0d..034c47a 100755
--- a/src/autodep/autodep
+++ b/src/autodep/autodep
@@ -80,10 +80,35 @@ def init_runtime_vars(portage_api, options,args):
else:
runtime_vars["is_emerge"]=False
+ runtime_vars["deps_all"]=[]
+
+ # find a full path to the program
+ program_path=None
+ program_name=args[0]
+ def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+ fpath, fname = os.path.split(program_name)
+ if fpath:
+ if is_exe(program_name):
+ program_path=program_name
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ exe_file = os.path.join(path, program_name)
+ if is_exe(exe_file):
+ program_path=exe_file
+
+ if program_path==None:
+ print("Failed to find the program %s. Check its existance."
+ % program_name)
+ exit(1)
+
+ runtime_vars["full_path"]=program_path
+
return runtime_vars
-def get_filter_function(options,system_packages,portage_api):
+def get_filter_function(options,args,system_packages,portage_api):
# handling --block
# exits if package name is bad
if not options.packages and not options.strict_block:
@@ -107,14 +132,18 @@ def get_filter_function(options,system_packages,portage_api):
#exit(1)
elif options.strict_block: # this option is very strict
# because blocking logic is complex
+
print "Building a list of files to block. This may take some time"
# we get list of all files and substract list of allowed files from it
allfiles=portage_utils.get_all_packages_files()
allowedpkgs=[]
allowedpkgs+=system_packages
if runtime_vars["is_emerge"]: # blocking logic for emerge
+ print "Notice: you can use emerge_strict command instead of autodep emerge."
+ print "Using this command allows to build any number of a packages.\n"
+
# including all dependencies of portage
- allowedpkgs+=list(portage_api.get_deps('portage'))
+ allowedpkgs+=list(portage_api.get_dep("portage",["RDEPEND"]))
(emergeaction ,emergeopts, emergefiles)=runtime_vars["emerge_parameters"]
if len(emergefiles)>1:
print "You can't install several packages with option -b"
@@ -122,35 +151,40 @@ def get_filter_function(options,system_packages,portage_api):
if len(runtime_vars["mergelist"])!=1:
print "You can't install several packages with option -b."
print "Emerge tried to install several packages: %s. " % runtime_vars["mergelist"]
- print "You can force emerge to merge a package wit hout any other "\
+ print "You can force emerge to merge a package without any other "\
"packages with emerge --nodeps option or you can install these "\
"packages first"
exit(1)
pkg=runtime_vars["mergelist"][0]
- depslist=list(portage_api.get_deps(pkg))
+ depslist=list(portage_api.get_deps_for_package_building(pkg))
allowedpkgs+=depslist
+ # manually add all python interpreters to this list
+ allowedpkgs+=["python"]
else:
- pass # TODO: blocking logic for non-emerge proccesses
-
- # always include current python interpreter
- #print allowedpkgs
- #allowedpkgs+=portage_utils.getpackagesbyfiles(sys.executable)
- #print allowedpkgs
+ program_path=runtime_vars["full_path"]
+ file_to_package=portage_utils.getpackagesbyfiles([program_path])
+ if program_path not in file_to_package:
+ print "Failed to find a package for %s" % program_path
+ else:
+ allowedpkgs+=[file_to_package[program_path]]
+ depslist=list(
+ portage_api.get_deps(file_to_package[program_path],["RDEPEND"]))
+ allowedpkgs+=depslist
+
+ print allowedpkgs
+
+ # remember the allowedpkgs in deps_all. It is bad to do it here.
+ runtime_vars["deps_all"]=allowedpkgs
allowedfiles=[]
for pkg in allowedpkgs:
allowedfiles+=portage_utils.getfilesbypackage(pkg)
- # manually add all python interpreters to this list
- allowedfiles+=portage_utils.getfilesbypackage('python')
- # manually add sandbox to this list
- #allowedfiles+=portage_utils.getfilesbypackage('sandbox')
-
+
allowedfiles=set(allowedfiles)
deniedfiles=allfiles-allowedfiles
-
print "The list size is about %dM" % (int(sys.getsizeof(deniedfiles))/1024/1024)
def filter(eventname,filename,stage):
if filename in deniedfiles:
@@ -158,15 +192,13 @@ def get_filter_function(options,system_packages,portage_api):
return True
return filter
-
-
portage_api, system_packages=init_environment()
options,args=parse_args()
runtime_vars=init_runtime_vars(portage_api,options,args)
color_printer=colorize_output.color_printer(not options.nocolor)
-filter_function=get_filter_function(options,system_packages,portage_api)
+filter_function=get_filter_function(options,args,system_packages,portage_api)
# launching program
events=logfs.fstracer.getfsevents(args[0], args,approach=options.approach,filterproc=filter_function)
@@ -180,11 +212,11 @@ if runtime_vars["is_emerge"]:
runtime_vars["deps_buildtime"]=set([])
for pkg in runtime_vars["mergelist"]:
runtime_vars["deps_all"]=runtime_vars["deps_all"].union(
- portage_api.get_deps(pkg,["DEPEND", "RDEPEND"]))
+ portage_api.get_deps_for_package_building(pkg))
runtime_vars["deps_buildtime"]=runtime_vars["deps_buildtime"].union(
portage_api.get_dep(pkg,["DEPEND"]))
- runtime_vars["deps_portage"]=portage_api.get_deps('portage',["DEPEND", "RDEPEND"])
+ runtime_vars["deps_portage"]=portage_api.get_dep('portage',["RDEPEND"])
#pkgs=portage_log_parser.get_list_of_merged_packages(
@@ -274,10 +306,9 @@ for package in sorted(packagesinfo):
if package=="unknown" and not options.verbose:
continue
- if package in system_packages and not options.verbose:
- continue
- is_pkg_in_dep=runtime_vars["is_emerge"] and package in runtime_vars["deps_all"]
+ is_pkg_in_dep=package in runtime_vars["deps_all"]
+ is_pkg_in_system=package in system_packages
is_pkg_in_portage_dep=runtime_vars["is_emerge"] and package in runtime_vars["deps_portage"]
is_pkg_python="dev-lang/python" in package
@@ -310,8 +341,10 @@ for package in sorted(packagesinfo):
]
- if not runtime_vars["is_emerge"] or is_pkg_in_dep:
+ if is_pkg_in_dep:
color_printer.printmsg("text","[OK]")
+ elif is_pkg_in_system:
+ color_printer.printmsg("text","[SYSTEM]")
elif is_pkg_in_portage_dep:
color_printer.printmsg("text","[PORTAGE DEP]")
elif is_pkg_python:
@@ -345,8 +378,8 @@ for package in sorted(packagesinfo):
filescounter+=1
if options.show_files:
continue
- elif filescounter>=options.numfiles:
- print " ..."
+ elif filescounter>options.numfiles:
+ print " ... and %d more ...\n" % (len(filenames)-10)
break
# print not founded files with stages
diff --git a/src/autodep/helpers/events_analysis.py b/src/autodep/helpers/events_analysis.py
index eba903a..b1e467d 100644
--- a/src/autodep/helpers/events_analysis.py
+++ b/src/autodep/helpers/events_analysis.py
@@ -39,4 +39,3 @@ def is_package_useful(pkg,stages,files):
return True
- \ No newline at end of file
diff --git a/src/autodep/logfs/fstracer.py b/src/autodep/logfs/fstracer.py
index 58507bb..f33d1fb 100644
--- a/src/autodep/logfs/fstracer.py
+++ b/src/autodep/logfs/fstracer.py
@@ -175,11 +175,11 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
if message[4]=="ASKING":
if filterproc(message[1],message[2],message[3]):
#print "Allowing an access to %s" % message[2]
- s.sendall("ALLOW\0"); # TODO: think about flush here
+ s.sendall("ALLOW\0");
else:
- print "Blocking an access to %s" % message[2]
- s.sendall("DENY\0"); # TODO: think about flush here
+ #print "Blocking an access to %s" % message[2]
+ s.sendall("DENY\0");
else:
eventname,filename,stage,result=message[1:5]
@@ -189,6 +189,10 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
hashofsucesses=events[stage][0]
hashoffailures=events[stage][1]
+
+ if result=="DENIED":
+ print "Blocking an access to %s" % filename
+
if result=="OK":
if not filename in hashofsucesses:
diff --git a/src/autodep/package_utils/portage_misc_functions.py b/src/autodep/package_utils/portage_misc_functions.py
index 95c4ce4..aa95845 100644
--- a/src/autodep/package_utils/portage_misc_functions.py
+++ b/src/autodep/package_utils/portage_misc_functions.py
@@ -117,13 +117,25 @@ class portage_api:
return ret
# we found the best visible match in common tree
+ #import pdb; pdb.set_trace()
metadata = dict(zip(self.metadata_keys,
self.portdb.aux_get(pkg, self.metadata_keys)))
dep_str = " ".join(metadata[k] for k in dep_type)
+
+ # the IUSE default are very important for us
+ iuse_defaults=[
+ u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
+
+ use=self.use.split()
+
+ for u in iuse_defaults:
+ if u not in use:
+ use.append(u)
+
success, atoms = portage.dep_check(dep_str, None, self.settings,
- myuse=self.use.split(), trees=portage.db, myroot=self.settings["ROOT"])
+ myuse=use, trees=portage.db, myroot=self.settings["ROOT"])
if not success:
return ret
@@ -176,8 +188,18 @@ class portage_api:
metadata = dict(zip(self.metadata_keys, self.vardb.aux_get(p, self.metadata_keys)))
dep_str = " ".join(metadata[k] for k in dep_type)
-
- success, atoms = portage.dep_check(dep_str, None, self.settings, myuse=self.use.split(),
+
+ # the IUSE default are very important for us
+ iuse_defaults=[
+ u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
+
+ use=self.use.split()
+
+ for u in iuse_defaults:
+ if u not in use:
+ use.append(u)
+
+ success, atoms = portage.dep_check(dep_str, None, self.settings, myuse=use,
trees=portage.db, myroot=self.settings["ROOT"])
if not success:
@@ -195,6 +217,19 @@ class portage_api:
unknown_packages.add(pkg)
return ret
+ def get_deps_for_package_building(self, pkg):
+ """
+ returns buildtime dependencies of current package and
+ all runtime dependencies of that buildtime dependencies
+ """
+ buildtime_deps=self.get_dep(pkg, ["DEPEND"])
+ runtime_deps=set()
+ for dep in buildtime_deps:
+ runtime_deps=runtime_deps.union(self.get_deps(dep,["RDEPEND"]))
+
+ ret=buildtime_deps.union(runtime_deps)
+ return ret
+
def get_system_packages_list(self):
"""
returns all packages from system set. They are always implicit dependencies
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) {