diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/migrate-pax | 20 | ||||
-rwxr-xr-x | scripts/pypaxctl | 99 | ||||
-rwxr-xr-x | scripts/revdep-pax | 171 |
3 files changed, 150 insertions, 140 deletions
diff --git a/scripts/migrate-pax b/scripts/migrate-pax index 429d45c..8593271 100755 --- a/scripts/migrate-pax +++ b/scripts/migrate-pax @@ -19,7 +19,8 @@ # We use portage's NEEDED.ELF.2 file. The format is in # /usr/lib/portage/bin/misc-functions.sh ~line 520 -# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 +# echo "${arch:3};${obj};${soname};${rpath};${needed}" \ +# >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 import os import re @@ -28,6 +29,7 @@ import sys import pax import portage + def get_objects(): vardb = portage.db[portage.root]["vartree"].dbapi @@ -36,11 +38,11 @@ def get_objects(): for pkg in vardb.cpv_all(): needed = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() - if not needed: # Some packages have no NEEDED.ELF.2 + if not needed: # Some packages have no NEEDED.ELF.2 continue for line in re.split('\n', needed): link = re.split(';', line) - objects.append(link[1]) # link[1] is the ELF object + objects.append(link[1]) # link[1] is the ELF object return objects @@ -69,7 +71,7 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'vmdh') except getopt.GetoptError as err: - print(str(err)) # will print something like 'option -a not recognized' + print(str(err)) # will print something like 'option -a not recognized' run_usage() sys.exit(1) @@ -102,7 +104,7 @@ def main(): run_usage() sys.exit(0) - if opt_count == 0 or opt_count > 2 or ( do_migration and do_deleteall): + if opt_count == 0 or opt_count > 2 or (do_migration and do_deleteall): run_usage() sys.exit(1) @@ -111,7 +113,8 @@ def main(): try: from pax import deletextpax except ImportError: - print('ERROR: Python module pax.so was compiled without XATTR_PAX support, cannot migrate or delete XATTR_PAX') + print('ERROR: Python module pax.so was compiled without XATTR_PAX support, ' + 'cannot migrate or delete XATTR_PAX') sys.exit(1) objects = get_objects() @@ -131,8 +134,9 @@ def main(): print("NONE: %s" % elf) if do_migration: - flags = re.sub('-','',flags) - if flags == 'e': continue # Don't create XATTR_PAX for default + flags = re.sub('-', '', flags) + if flags == 'e': + continue # Don't create XATTR_PAX for default pax.setstrflags(elf, flags) if do_deleteall: diff --git a/scripts/pypaxctl b/scripts/pypaxctl index cca3d2c..cfae4d3 100755 --- a/scripts/pypaxctl +++ b/scripts/pypaxctl @@ -24,62 +24,65 @@ import pax xattr_available = True try: - from pax import deletextpax + from pax import deletextpax except ImportError: - xattr_available = False + deletextpax = '' + xattr_available = False + def run_usage(): - print('Package Name : elfix') - print('Bug Reports : http://bugs.gentoo.org/') - print('Program Name : pypaxctl') - if xattr_available: - print('Description : Get/set/delete PT_PAX or XATTR_PAX flags on an ELF object') - print('') - print('Usage : pypaxctl -g ELF get XATTR_PAX flags first, else get PT_PAX flags') - print(' : pypaxctl -s [-PpEeMmRrSs] ELF set PT_PAX and XATTR_PAX flags whenever possible') - print(' : pypaxctl -d ELF delete the XATTR_PAX field') - else: - print('Description : Get/set PT_PAX flags on an ELF object') - print('') - print('Usage : pypaxctl -g ELF get PT_PAX flags') - print(' : pypaxctl -s [-PpEeMmRrSs] ELF set PT_PAX flags whenever possible') - print('') - print('Note : Python module pax.so was compiled without XATTR_PAX support') - print('') + print('Package Name : elfix') + print('Bug Reports : http://bugs.gentoo.org/') + print('Program Name : pypaxctl') + xattr_message = '''Description : Get/set/delete PT_PAX or XATTR_PAX flags on an ELF object + +Usage : pypaxctl -g ELF get XATTR_PAX flags first, else get PT_PAX flags + : pypaxctl -s [-PpEeMmRrSs] ELF set PT_PAX and XATTR_PAX flags whenever possible + : pypaxctl -d ELF delete the XATTR_PAX field''' + if xattr_available: + print(xattr_message) + else: + print('Description : Get/set PT_PAX flags on an ELF object') + print('') + print('Usage : pypaxctl -g ELF get PT_PAX flags') + print(' : pypaxctl -s [-PpEeMmRrSs] ELF set PT_PAX flags whenever possible') + print('') + print('Note : Python module pax.so was compiled without XATTR_PAX support') + print('') def main(): - try: - if xattr_available: - opts, args = getopt.getopt(sys.argv[1:], 'gs:d') - else: - opts, args = getopt.getopt(sys.argv[1:], 'gs:') - except getopt.GetoptError as err: - print(err) - sys.exit(1) + try: + if xattr_available: + opts, args = getopt.getopt(sys.argv[1:], 'gs:d') + else: + opts, args = getopt.getopt(sys.argv[1:], 'gs:') + except getopt.GetoptError as err: + print(err) + sys.exit(1) - if( len(opts) != 1 or len(args) < 1 ): - run_usage() - sys.exit(1) + if (len(opts) != 1) or (len(args) < 1): + run_usage() + sys.exit(1) - for o, a in opts: - if o == '-g': - for elf in args: - ( str_flags, bin_flags ) = pax.getflags(elf) - print('%s' % str_flags) - elif o == '-s': - for elf in args: - pax.setstrflags(elf, a) + for o, a in opts: + if o == '-g': + for elf in args: + (str_flags, bin_flags) = pax.getflags(elf) + print('%s' % str_flags) + elif o == '-s': + for elf in args: + pax.setstrflags(elf, a) - # Don't worry if xattr_available = False - # because we can't get here if it is. - else: - for elf in args: - try: - pax.deletextpax(elf) - except pax.PaxError: - print('pax_deletextpax: XATTR_PAX not supported') - sys.exit(1) + # Don't worry if xattr_available = False + # because we can't get here if it is. + else: + for elf in args: + try: + pax.deletextpax(elf) + except pax.PaxError: + print('pax_deletextpax: XATTR_PAX not supported') + sys.exit(1) if __name__ == '__main__': - main() + main() diff --git a/scripts/revdep-pax b/scripts/revdep-pax index b919dbf..ebdea9c 100755 --- a/scripts/revdep-pax +++ b/scripts/revdep-pax @@ -23,14 +23,14 @@ # information we need generated by scanelf during emerge. # # See /usr/lib/portage/bin/misc-functions.sh ~line 520 -# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 +# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> \ +# "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 # import getopt import os import sys import pax - import re import portage @@ -66,11 +66,10 @@ class LinkMap: for pkg in vardb.cpv_all(): needed = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() - if needed: # Some packages have no NEEDED.ELF.2 + if needed: # Some packages have no NEEDED.ELF.2 self.pkgs.append(pkg) for line in re.split('\n', needed): - self.pkgs_needed.setdefault(pkg,[]).append(re.split(';', line)) - + self.pkgs_needed.setdefault(pkg, []).append(re.split(';', line)) def get_object_needed(self): """ Return object_needed dictionary which has structure @@ -91,11 +90,10 @@ class LinkMap: abi = link[0] elf = link[1] sonames = re.split(',', link[4]) - object_needed.setdefault(abi,{}).update({elf:sonames}) + object_needed.setdefault(abi, {}).update({elf: sonames}) return object_needed - def get_libraries(self): """ Return library2soname dictionary which has structure @@ -113,14 +111,13 @@ class LinkMap: abi = link[0] elf = link[1] soname = link[2] - if soname: #no soname => executable - library2soname[elf] = (soname,abi) - soname2library[(soname,abi)] = elf - - return ( library2soname, soname2library ) + if soname: # no soname => executable + library2soname[elf] = (soname, abi) + soname2library[(soname, abi)] = elf + return library2soname, soname2library - def get_soname_needed(self, object_needed, library2soname ): + def get_soname_needed(self, object_needed, library2soname): """ Return soname_needed dictionary which has structure: { @@ -137,14 +134,14 @@ class LinkMap: for elf in object_needed[abi]: try: (soname, abi_check) = library2soname[elf] - assert abi == abi_check # We should get the same abi associated with the soname - soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]}) + # We should get the same abi associated with the soname + assert abi == abi_check + soname_needed.setdefault(abi, {}).update({soname: object_needed[abi][elf]}) except KeyError: continue # no soname, its probably an executable return soname_needed - def expand_linkings(self, object_needed, soname2library): """ Expands the object_needed dictionary which has structure @@ -162,27 +159,32 @@ class LinkMap: for elf in object_needed[abi]: while True: found_new_soname = False - for so in object_needed[abi][elf]: # For all the first links ... + # For all the first links ... + for so in object_needed[abi][elf]: try: - for sn in object_needed[abi][soname2library[(so,abi)]]: # go to the next links ... - if sn in object_needed[abi][elf]: # skip if already included ... + # go to the next links ... + for sn in object_needed[abi][soname2library[(so, abi)]]: + # skip if already included ... + if sn in object_needed[abi][elf]: continue - if not (sn,abi) in soname2library: # skip if vdso ... + # skip if vdso ... + if not (sn, abi) in soname2library: continue - # This appends to the object_needed and soname_needed lists. No copy was - # done so its the same lists in memory for both, and its modified for both. + # This appends to the object_needed and soname_needed lists. No copy was + # done so its the same lists in memory for both, and its modified for both. - object_needed[abi][elf].append(sn) # otherwise collapse it back into - found_new_soname = True # first links of the chain. + # otherwise collapse it back into + object_needed[abi][elf].append(sn) + # first links of the chain. + found_new_soname = True - except KeyError: # Not all nodes in the chain have a next node + except KeyError: # Not all nodes in the chain have a next node continue if not found_new_soname: # We're done, that last iteration found break # no new nodes - def get_object_reverse_linkings(self, object_linkings): """ Return object_reverse_linkings dictionary which has structure @@ -197,11 +199,10 @@ class LinkMap: for abi in object_linkings: for elf in object_linkings[abi]: for soname in object_linkings[abi][elf]: - object_reverse_linkings.setdefault(abi,{}).setdefault(soname,[]).append(elf) + object_reverse_linkings.setdefault(abi, {}).setdefault(soname, []).append(elf) return object_reverse_linkings - def get_maps(self): """ Generate the full forward and reverse links using the above functions """ @@ -209,18 +210,16 @@ class LinkMap: # soname_linkings are only one step into the entire link chain. object_linkings = self.get_object_needed() - ( library2soname, soname2library ) = self.get_libraries() - soname_linkings = self.get_soname_needed( object_linkings, library2soname ) + (library2soname, soname2library) = self.get_libraries() + soname_linkings = self.get_soname_needed(object_linkings, library2soname) # After the appending in expand_linkings(), forward_linkings and soname_linkings # have been extended through the entire chain of linking. expand_linkings() is # a "side-effect" function, so we note it here. - self.expand_linkings( soname_linkings, soname2library ) - object_reverse_linkings = self.get_object_reverse_linkings( object_linkings ) - - return ( object_linkings, object_reverse_linkings, library2soname, soname2library ) - + self.expand_linkings(soname_linkings, soname2library) + object_reverse_linkings = self.get_object_reverse_linkings(object_linkings) + return object_linkings, object_reverse_linkings, library2soname, soname2library def print_problems(sonames_missing_library): @@ -231,7 +230,8 @@ def print_problems(sonames_missing_library): def run_forward(verbose): - (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + (object_linkings, object_reverse_linkings, + library2soname, soname2library) = LinkMap().get_maps() sonames_missing_library = [] @@ -257,7 +257,7 @@ def run_forward(verbose): sv = '%s\n\t%s\t%s ( %s )' % (sv, soname, library, library_str_flags) if elf_str_flags != library_str_flags: s = '%s\n\t%s\t%s ( %s )' % (s, soname, library, library_str_flags) - count = count + 1 + count += 1 except KeyError: sonames_missing_library.append(soname) @@ -276,9 +276,10 @@ def run_forward(verbose): def run_reverse(verbose, executable_only): - (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + (object_linkings, object_reverse_linkings, + library2soname, soname2library) = LinkMap().get_maps() - shell_path = path = os.getenv('PATH').split(':') + shell_path = os.getenv('PATH').split(':') sonames_missing_library = [] @@ -306,12 +307,12 @@ def run_reverse(verbose, executable_only): sv = '%s\n\t%s ( %s )' % (sv, elf, elf_str_flags) if library_str_flags != elf_str_flags: s = '%s\n\t%s ( %s )' % (s, elf, elf_str_flags) - count = count + 1 + count += 1 else: sv = '%s\n\t%s ( %s )' % (sv, elf, elf_str_flags) if library_str_flags != elf_str_flags: s = '%s\n\t%s ( %s )' % (s, elf, elf_str_flags) - count = count + 1 + count += 1 if verbose: print('%s\n' % sv) @@ -345,12 +346,12 @@ def migrate_flags(importer, exporter_str_flags, exporter_bin_flags): #See /usr/include/elf.h for these values pf_flags = { - 'P':1<<4, 'p':1<<5, - 'S':1<<6, 's':1<<7, - 'M':1<<8, 'm':1<<9, - 'X':1<<10, 'x':1<<11, - 'E':1<<12, 'e':1<<13, - 'R':1<<14, 'r':1<<15 + 'P': 1 << 4, 'p': 1 << 5, + 'S': 1 << 6, 's': 1 << 7, + 'M': 1 << 8, 'm': 1 << 9, + 'X': 1 << 10, 'x': 1 << 11, + 'E': 1 << 12, 'e': 1 << 13, + 'R': 1 << 14, 'r': 1 << 15 } try: @@ -373,10 +374,10 @@ def migrate_flags(importer, exporter_str_flags, exporter_bin_flags): result_bin_flags = result_bin_flags ^ pf_flags[exporter_str_flags[i]] result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]] print('\t\tWarning: %s has %s, refusing to set to %s' % ( - importer, importer_str_flags[i], exporter_str_flags[i] )), + importer, importer_str_flags[i], exporter_str_flags[i])), # The exporter's flags is off, so use the importer's flag - if (exporter_str_flags[i] == '-' and importer_str_flags[i] != '-'): + if (exporter_str_flags[i] == '-') and (importer_str_flags[i] != '-'): result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]] pax.setbinflags(importer, result_bin_flags) @@ -394,16 +395,17 @@ def run_elf(elf, verbose, mark, allyes): print('%s: No PAX flags found\n' % elf) return - (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + (object_linkings, object_reverse_linkings, + library2soname, soname2library) = LinkMap().get_maps() mismatched_libraries = [] for abi in object_linkings: - if not elf in object_linkings[abi]: # There may be no elf for that abi + if not elf in object_linkings[abi]: # There may be no elf for that abi continue for soname in object_linkings[abi][elf]: try: - library = soname2library[(soname,abi)] + library = soname2library[(soname, abi)] try: (library_str_flags, library_bin_flags) = pax.getflags(library) except pax.PaxError: @@ -444,7 +446,7 @@ def run_elf(elf, verbose, mark, allyes): try: migrate_flags(library, elf_str_flags, elf_bin_flags) except pax.PaxError: - print('\n\tCould not set PAX flags on %s, text maybe busy' % (library, abi)) + print('\n\tCould not set PAX flags on %s, text maybe busy' % library) try: (library_str_flags, library_bin_flags) = pax.getflags(library) @@ -454,9 +456,10 @@ def run_elf(elf, verbose, mark, allyes): def run_soname(name, verbose, use_soname, mark, allyes, executable_only): - shell_path = path = os.getenv('PATH').split(':') + shell_path = os.getenv('PATH').split(':') - (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + (object_linkings, object_reverse_linkings, + library2soname, soname2library) = LinkMap().get_maps() if use_soname: soname = name @@ -476,7 +479,6 @@ def run_soname(name, verbose, use_soname, mark, allyes, executable_only): print('%s\tNo such LIBRARY' % name) return - mismatched_elfs = [] for abi in abi_list: @@ -487,15 +489,15 @@ def run_soname(name, verbose, use_soname, mark, allyes, executable_only): library = soname2library[(soname, abi)] try: - (library_str_flags, library_bin_flags) = pax.getflags(library) - print('%s\t%s :%s (%s)\n' % (soname, library, abi, library_str_flags)) + (library_str_flags, library_bin_flags) = pax.getflags(library) + print('%s\t%s :%s (%s)\n' % (soname, library, abi, library_str_flags)) except pax.PaxError: - print('%s :%s : No PAX flags found\n' % (library, abi)) - continue + print('%s :%s : No PAX flags found\n' % (library, abi)) + continue for elf in object_reverse_linkings[abi][soname]: try: - (elf_str_flags, elf_bin_flags ) = pax.getflags(elf) + (elf_str_flags, elf_bin_flags) = pax.getflags(elf) except pax.PaxError: elf_str_flags = '****' if verbose: @@ -551,22 +553,23 @@ def run_soname(name, verbose, use_soname, mark, allyes, executable_only): def run_usage(): - print('Package Name : elfix') - print('Bug Reports : http://bugs.gentoo.org/') - print('Program Name : revdep-pax') - print('Description : Get or set pax flags on an ELF object') - print('') - print('Usage : revdep-pax -f [-v] print out all forward mappings for all system ELF objects') - print(' : revdep-pax -r [-ve] print out all reverse mappings for all system sonames') - print(' : revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT') - print(' : revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME') - print(' : revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file') - print(' : revdep-pax [-h] print out this help') - print(' : -v verbose, otherwise just print mismatching objects') - print(' : -e only print out executables in shell $PATH') - print(' : -m don\'t just report, but mark the mismatching objects') - print(' : -y assume "yes" to all prompts for marking (USE CAREFULLY!)') - print('') + usage = '''Package Name : elfix +Bug Reports : http://bugs.gentoo.org/ +Program Name : revdep-pax +Description : Get or set pax flags on an ELF object + +Usage : revdep-pax -f [-v] print all forward mappings for all system ELF objects + : revdep-pax -r [-ve] print all reverse mappings for all system sonames + : revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT + : revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME + : revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file + : revdep-pax [-h] print this help + : -v verbose, otherwise just print mismatching objects + : -e only print executables in shell $PATH + : -m don\'t just report, but mark the mismatching objects + : -y assume "yes" to all prompts for marking (BE CAREFULL) +''' + print(usage) def main(): @@ -579,7 +582,7 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:vemy') except getopt.GetoptError as err: - print(str(err)) # will print something like 'option -a not recognized' + print(str(err)) # will print something like 'option -a not recognized' run_usage() sys.exit(1) @@ -587,12 +590,12 @@ def main(): run_usage() sys.exit(1) - do_usage = False + do_usage = False do_forward = False do_reverse = False - elf = None - soname = None + elf = None + soname = None library = None verbose = False @@ -641,11 +644,11 @@ def main(): run_forward(verbose) elif do_reverse: run_reverse(verbose, executable_only) - elif elf != None: + elif elf is not None: run_elf(elf, verbose, mark, allyes) - elif soname != None: + elif soname is not None: run_soname(soname, verbose, True, mark, allyes, executable_only) - elif library != None: + elif library is not None: library = os.path.realpath(library) run_soname(library, verbose, False, mark, allyes, executable_only) |