diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2012-12-26 20:58:33 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2012-12-28 20:11:29 -0500 |
commit | 29630e205dcfda04d87679a2156948bd86c1a6a9 (patch) | |
tree | 3a627cc0bf5c70952fd9d8d4cf99ec5faca12117 | |
parent | misc/link_map.py: place class in its own module (diff) | |
download | elfix-29630e205dcfda04d87679a2156948bd86c1a6a9.tar.gz elfix-29630e205dcfda04d87679a2156948bd86c1a6a9.tar.bz2 elfix-29630e205dcfda04d87679a2156948bd86c1a6a9.zip |
misc/alt-revdep-pax: cleanup wrt object with no pax flags
-rw-r--r-- | .gitignore | 3 | ||||
-rwxr-xr-x | misc/alt-revdep-pax | 1001 |
2 files changed, 433 insertions, 571 deletions
@@ -21,3 +21,6 @@ paxctl-ng bad-gnustack daemon revdepbin +# +scripts/build +misc/__pycache__ diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax index 69086af..be51bf9 100755 --- a/misc/alt-revdep-pax +++ b/misc/alt-revdep-pax @@ -1,20 +1,20 @@ #!/usr/bin/env python # -# alt-revdep-pax: this file is part of the elfix package -# Copyright (C) 2011 Anthony G. Basile +# alt-revdep-pax: this file is part of the elfix package +# Copyright (C) 2011 Anthony G. Basile # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. # # @@ -29,590 +29,449 @@ import getopt import os import sys -import re import pax -import portage +from link_map import LinkMap -""" python2/3 compat input """ def get_input(prompt): - if sys.hexversion > 0x03000000: - return input(prompt) - else: - return raw_input(prompt) - - -""" -Return object_needed dictionary which has structure - - { full_path_to_ELF_object : [ soname1, soname2, ... ], ... } - -Here the sonames were obtained from the ELF object by scanelf -nm -(like readelf -d) during emerge. -""" -def get_object_needed(): - - vardb = portage.db[portage.root]["vartree"].dbapi - - object_needed = {} - - for pkg in vardb.cpv_all(): - needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() - if not needs: #skip empty lines - continue - lines = re.split('\n', needs) - for line in lines: - link = re.split(';', line) - elf = link[1] - sonames = re.split(',', link[4]) - object_needed[elf] = sonames - - return object_needed - - -""" -Return library2soname dictionary which has structure - - { full_path_to_library : soname, ... } - -and its inverse which has structure - - { soname : full_path_to_library, ... } -""" -def get_libraries(): - - vardb = portage.db[portage.root]["vartree"].dbapi - - library2soname = {} - soname2library = {} - - for pkg in vardb.cpv_all(): - needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() - if not needs: #skip empty lines - continue - lines = re.split('\n', needs) - for line in lines: - link = re.split(';', line) - elf = link[1] - soname = link[2] - if soname: #no soname => executable - library2soname[elf] = soname - soname2library[soname] = elf - - return ( library2soname, soname2library ) - - -""" -Return get_soname_needed dictionary which has structure: - - { soname : [ soname1, soname2, ... ], .... } - -Here the soname1, soname2,... were obtained from soname's corresponding -ELF object by scanelf -n during emerge. -""" -def get_soname_needed( object_needed, library2soname ): - - soname_needed = {} - - for elf in object_needed: - try: - soname = library2soname[elf] - soname_needed[soname] = object_needed[elf] - except KeyError: - continue # no soname, its probably an executable - - return soname_needed - -""" -Run through the entire chain of obj -> sonameX -> sonameY ... -> sonameZ chain. -We do this by continuously expanding the list value of the dictionary key elf -entry until there are no new soname's found. -""" -def expand_linkings( object_needed, soname2library ): - - for elf in object_needed: - while True: - found_new_soname = False - for s in object_needed[elf]: # For all the next links ... - try: - for sf in object_needed[soname2library[s]]: # ... go one step ahead in the chain - if sf in object_needed[elf]: # ... skip it if we already included it - continue - if not sf in soname2library: # ... skip if its a vdso - 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. - object_needed[elf].append(sf) # ... otherwise collapse it back into - found_new_soname = True # first node of the chain. - - 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_linkings(): - - object_needed = get_object_needed() - ( library2soname, soname2library ) = get_libraries() - soname_needed = get_soname_needed( object_needed, library2soname ) - expand_linkings( object_needed, soname2library ) - return ( object_needed, soname2library ) - - -def print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library): - - elfs_without_flags = set(elfs_without_flags) - print('\n**** ELF objections without any PAX flags ****\n') - for m in elfs_without_flags: - print('\t%s' % m) - - sonames_without_flags = set(sonames_without_flags) - print('\n**** SONAMEs with library files without PAX flags ****\n') - for m in sonames_without_flags: - print('\t%s' % m) - - sonames_missing_library = set(sonames_missing_library) - print('\n**** SONAMES without any library files ****\n') - for m in sonames_missing_library: - print('\t%s' % m) - - -def print_object_linkings( object_linkings, soname2library, verbose ): - - elfs_without_flags = [] - sonames_without_flags = [] - sonames_missing_library = [] - - for elf in object_linkings: - try: - ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf) - sv = '%s ( %s )\n' % ( elf, elf_str_flags ) - s = sv - except pax.PaxError: - elfs_without_flags.append(elf) - continue - - count = 0 - for soname in object_linkings[elf]: - try: - library = soname2library[soname] - ( library_str_flags, library_bin_flags ) = pax.getflags(library) - 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 - except KeyError: - sonames_missing_library.append(soname) - except pax.PaxError: - sonames_without_flags.append(soname) - - - if verbose: - print('%s\n' % sv) - if count == 0: - print('\tNo mismatches\n\n') - else: - print('\tMismatches\n\n') - else: - if count != 0: - print('%s\n\n' % s) - - print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library) - + """ python2/3 compat input """ + if sys.hexversion > 0x03000000: + return input(prompt) + else: + return raw_input(prompt) + + +def print_problems(elfs_without_flags, sonames_without_flags, sonames_missing_library): + elfs_without_flags = set(elfs_without_flags) + print('\n**** ELF objections without any PAX flags ****') + for m in elfs_without_flags: + print('\t%s' % m) + sonames_without_flags = set(sonames_without_flags) + print('\n**** SONAMEs with library files without PAX flags ****') + for m in sonames_without_flags: + print('\t%s' % m) + sonames_missing_library = set(sonames_missing_library) + print('\n**** SONAMES without any library files ****') + for m in sonames_missing_library: + print('\t%s' % m) def run_forward(verbose): - - ( object_linkings, soname2library ) = get_object_linkings() - print_object_linkings( object_linkings, soname2library, verbose) - - - - -def get_object_reverse_linkings( object_linkings ): - - object_reverse_linkings = {} - - for elf in object_linkings: - for soname in object_linkings[elf]: - object_reverse_linkings.setdefault(soname,[]).append(elf) - - return object_reverse_linkings - - -def print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only): - - shell_path = path = os.getenv('PATH').split(':') - - elfs_without_flags = [] - sonames_without_flags = [] - sonames_missing_library = [] - - for soname in object_reverse_linkings: - try: - library = soname2library[soname] - ( library_str_flags, library_bin_flags ) = pax.getflags(library) - sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags ) - s = sv - except KeyError: - sonames_missing_library.append(soname) - except pax.PaxError: - sonames_without_flags.append(soname) - - count = 0 - for elf in object_reverse_linkings[soname]: - try: - ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf) - if executable_only: - if os.path.dirname(elf) in shell_path: - 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 - 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 - except pax.PaxError: - elfs_without_flags.append(elf) - - if verbose: - print('%s\n' % sv) - if count == 0: - print('\tNo mismatches\n\n') - else: - print('\tMismatches\n\n') - else: - if count != 0: - print('%s\n\n' % s) - - print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library) + (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + + elfs_without_flags = [] + sonames_without_flags = [] + sonames_missing_library = [] + + for abi in object_linkings: + for elf in object_linkings[abi]: + try: + (elf_str_flags, elf_bin_flags) = pax.getflags(elf) + sv = '%s :%s ( %s )' % (elf, abi, elf_str_flags) + s = sv + except pax.PaxError: + elfs_without_flags.append(elf) + continue + + count = 0 + for soname in object_linkings[abi][elf]: + try: + library = soname2library[(soname,abi)] + (library_str_flags, library_bin_flags) = pax.getflags(library) + 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 + except KeyError: + sonames_missing_library.append(soname) + except pax.PaxError: + sonames_without_flags.append(soname) + + if verbose: + print('%s\n' % sv) + if count == 0: + print('\tNo mismatches\n\n') + else: + print('\tMismatches\n\n') + else: + if count != 0: + print('%s\n\n' % s) + + if verbose: + print_problems(elfs_without_flags, sonames_without_flags, sonames_missing_library) def run_reverse(verbose, executable_only): - ( object_linkings, soname2library ) = get_object_linkings() - object_reverse_linkings = get_object_reverse_linkings( object_linkings ) - print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only) - - + (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + + shell_path = path = os.getenv('PATH').split(':') + + elfs_without_flags = [] + sonames_without_flags = [] + sonames_missing_library = [] + + for abi in object_reverse_linkings: + for soname in object_reverse_linkings[abi]: + try: + library = soname2library[(soname,abi)] + (library_str_flags, library_bin_flags) = pax.getflags(library) + sv = '%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags) + s = sv + except KeyError: + sonames_missing_library.append(soname) + except pax.PaxError: + sonames_without_flags.append(soname) + + count = 0 + for elf in object_reverse_linkings[abi][soname]: + try: + (elf_str_flags, elf_bin_flags) = pax.getflags(elf) + if executable_only: + if os.path.dirname(elf) in shell_path: + 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 + 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 + except pax.PaxError: + elfs_without_flags.append(elf) + + if verbose: + print('%s\n' % sv) + if count == 0: + print('\tNo mismatches\n\n') + else: + print('\tMismatches\n\n') + else: + if count != 0: + print('%s\n\n' % s) + + if verbose: + print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library) def migrate_flags(importer, exporter_str_flags, exporter_bin_flags): - # We implement the following logic for setting the pax flags - # on the target elf object, the IMPORTER, given that the flags - # from the elf object we want it to match to, the EXPORTER. - # - # EXPORTER IMPORTER RESULT - # On On On - # On Off On + Warn - # On - On - # Off On On + Warn - # Off Off Off - # Off - Off - # - On On - # - Off Off - # - - - - - #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 - } - - ( importer_str_flags, importer_bin_flags ) = pax.getflags(importer) - - # Start with the exporter's flags - result_bin_flags = exporter_bin_flags - - for i in range(len(importer_str_flags)): - - # The exporter's flag contradicts the importer's flag, so do nothing - if (exporter_str_flags[i].isupper() and importer_str_flags[i].islower()) or \ - (exporter_str_flags[i].islower() and importer_str_flags[i].isupper()): - - # Revert the exporter's flag, use the importer's flag and warn - 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] )), - - # The exporter's flags is off, so use the importer's flag - 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) + # We implement the following logic for setting the pax flags + # on the target elf object, the IMPORTER, given that the flags + # from the elf object we want it to match to, the EXPORTER. + # + # EXPORTER IMPORTER RESULT + # On On On + # On Off On + Warn + # On - On + # Off On On + Warn + # Off Off Off + # Off - Off + # - On On + # - Off Off + # - - - + + #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 + } + + (importer_str_flags, importer_bin_flags) = pax.getflags(importer) + + # Start with the exporter's flags + result_bin_flags = exporter_bin_flags + + for i in range(len(importer_str_flags)): + + # The exporter's flag contradicts the importer's flag, so do nothing + if (exporter_str_flags[i].isupper() and importer_str_flags[i].islower()) or \ + (exporter_str_flags[i].islower() and importer_str_flags[i].isupper()): + + # Revert the exporter's flag, use the importer's flag and warn + 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] )), + + # The exporter's flags is off, so use the importer's flag + 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) def run_elf(elf, verbose, mark, allyes): + if not os.path.exists(elf): + print('%s\tNo such OBJECT' % elf) + return + + try: + (elf_str_flags, elf_bin_flags) = pax.getflags(elf) + print('%s (%s)\n' % (elf, elf_str_flags)) + except pax.PaxError: + print('%s: No PAX flags found\n' % elf) + return + + (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 + continue + for soname in object_linkings[abi][elf]: + try: + library = soname2library[(soname,abi)] + (library_str_flags, library_bin_flags) = pax.getflags(library) + if verbose: + print('\t%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags)) + if elf_str_flags != library_str_flags: + mismatched_libraries.append(library) + if not verbose: + print('\t%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags)) + except pax.PaxError: + print('%s :%s: file for soname not found' % (soname,abi)) + + if len(mismatched_libraries) == 0: + if not verbose: + print('\tNo mismatches\n') + else: + print('\n'), + if mark: + print('\tWill mark libraries with %s\n' % elf_str_flags) + for library in mismatched_libraries: + do_marking = False + while True: + if allyes: + ans = 'y' + else: + ans = get_input('\tSet flags for %s :%s (y/n): ' % (library,abi)) + if ans == 'y': + do_marking = True + break + elif ans == 'n': + do_marking = False + break + else: + print('\t\tPlease enter y or n') + + if do_marking: + 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)) + + try: + (library_str_flags, library_bin_flags) = pax.getflags(library) + print('\n\t\t%s ( %s )\n' % (library, library_str_flags)) + except pax.PaxError: + print('\n\t\t%s: Could not read PAX flags') - if not os.path.exists(elf): - print('%s\tNo such OBJECT' % elf) - return - - try: - (elf_str_flags, elf_bin_flags) = pax.getflags(elf) - print('%s (%s)\n' % (elf, elf_str_flags)) - except pax.PaxError: - print('%s: No PAX flags found\n' % elf) - return - - (object_linkings, soname2library) = get_object_linkings() - - mismatched_libraries = [] - - for soname in object_linkings[elf]: - try: - library = soname2library[soname] - ( library_str_flags, library_bin_flags ) = pax.getflags(library) - if verbose: - print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags )) - if elf_str_flags != library_str_flags: - mismatched_libraries.append(library) - if not verbose: - print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags )) - except pax.PaxError: - print('%s: file for soname not found' % soname) - - if len(mismatched_libraries) == 0: - if not verbose: - print('\tNo mismatches\n') - else: - print('\n'), - if mark: - print('\tWill mark libraries with %s\n' % elf_str_flags) - for library in mismatched_libraries: - do_marking = False - while True: - if allyes: - ans = 'y' - else: - ans = get_input('\tSet flags for %s (y/n): ' % library) - if ans == 'y': - do_marking = True - break - elif ans == 'n': - do_marking = False - break - else: - print('\t\tPlease enter y or n') - - if do_marking: - 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) - - try: - ( library_str_flags, library_bin_flags ) = pax.getflags(library) - print('\n\t\t%s ( %s )\n' % ( library, library_str_flags )) - except pax.PaxError: - print('\n\t\t%s: Could not read PAX flags') - - -def invert_so2library_mappings( so2library_mappings ): - library2soname_mappings = {} - for soname, library in so2library_mappings.items(): - library2soname_mappings[library] = soname - return library2soname_mappings - -#XXXXXXXXXXXXXXXXX def run_soname(name, verbose, use_soname, mark, allyes, executable_only): - shell_path = path = os.getenv('PATH').split(':') - - ( forward_linkings, so2library_mappings ) = get_object_linkings() - reverse_linkings = invert_linkings( forward_linkings ) - - if use_soname: - soname = name - else: - library2soname_mappings = invert_so2library_mappings(so2library_mappings) - try: - soname = library2soname_mappings[name] - except KeyError: - print('%s\tNo such LIBRARY' % name) - return - - try: - linkings = reverse_linkings[soname] - except KeyError: - print('%s\tNo such SONAME' % soname) - return - - library = so2library_mappings[soname] - - ( library_str_flags, library_bin_flags ) = pax.getflags(library) - print('%s\t%s (%s)\n' % ( soname, library, library_str_flags )) - - mismatched_binaries = [] - for binary in linkings: - try: - ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary) - if verbose: - if executable_only: - if os.path.dirname(binary) in shell_path: - print('\t%s ( %s )' % ( binary, binary_str_flags )) - else: - print('\t%s ( %s )' % ( binary, binary_str_flags )) - if library_str_flags != binary_str_flags: - if executable_only: - if os.path.dirname(binary) in shell_path: - mismatched_binaries.append(binary) - if not verbose: - print('\t%s ( %s )' % ( binary, binary_str_flags )) - else: - mismatched_binaries.append(binary) - if not verbose: - print('\t%s ( %s )' % ( binary, binary_str_flags )) - except pax.PaxError: - print('cannot obtain pax flags for %s' % binary) - - if len(mismatched_binaries) == 0: - if not verbose: - print('\tNo mismatches\n') - else: - print('\n'), - if mark: - print('\tWill mark binaries with %s\n' % library_str_flags) - for binary in mismatched_binaries: - if executable_only: - if not os.path.dirname(binary) in shell_path: - continue - do_marking = False - while True: - if allyes: - ans = 'y' - else: - ans = get_input('\tSet flags for %s (y/n): ' % binary) - if ans == 'y': - do_marking = True - break - elif ans == 'n': - do_marking = False - break - else: - print('\t\tPlease enter y or n') - if do_marking: - try: - migrate_flags(binary, library_str_flags, library_bin_flags) - except pax.PaxError: - print('\n\tCould not set pax flags on %s, file is probably busy' % binary) - print('\tShut down all processes that use it and try again') - ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary) - print('\n\t\t%s ( %s )\n' % ( binary, binary_str_flags )) + shell_path = path = os.getenv('PATH').split(':') + + (object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps() + + if use_soname: + soname = name + abi_list = object_reverse_linkings.keys() + for abi in abi_list: + # There must be at least on abi with that soname + if soname in object_reverse_linkings[abi]: + break + else: + print('%s\tNo such SONAME' % soname) + return + else: + try: + (soname, abi) = library2soname[name] + abi_list = [abi] + except KeyError: + print('%s\tNo such LIBRARY' % name) + return + + + mismatched_elfs = [] + + for abi in abi_list: + # An soname can belong to one or more abis + if not soname in object_reverse_linkings[abi]: + continue + + library = soname2library[(soname,abi)] + (library_str_flags, library_bin_flags) = pax.getflags(library) + print('%s\t%s :%s (%s)\n' % (soname, library, ", ".join(abi_list), library_str_flags)) + + for elf in object_reverse_linkings[abi][soname]: + try: + (elf_str_flags, elf_bin_flags ) = pax.getflags(elf) + if verbose: + if executable_only: + if os.path.dirname(elf) in shell_path: + print('\t%s ( %s )' % (elf, elf_str_flags )) + else: + print('\t%s ( %s )' % ( elf, elf_str_flags )) + if library_str_flags != elf_str_flags: + if executable_only: + if os.path.dirname(elf) in shell_path: + mismatched_elfs.append(elf) + if not verbose: + print('\t%s ( %s )' % (elf, elf_str_flags )) + else: + mismatched_elfs.append(elf) + if not verbose: + print('\t%s ( %s )' % (elf, elf_str_flags )) + except pax.PaxError: + # If you can't get the pax flags, then its automatically mismatched + if executable_only: + if os.path.dirname(elf) in shell_path: + mismatched_elfs.append(elf) + if not verbose: + print('\t%s ( %s )' % (elf, '****' )) + else: + mismatched_elfs.append(elf) + if not verbose: + print('\t%s ( %s )' % (elf, '****' )) + + if len(mismatched_elfs) == 0: + if not verbose: + print('\tNo mismatches\n') + else: + print('\n'), + if mark: + print('\tWill mark elf with %s\n' % library_str_flags) + for elf in mismatched_elfs: + if executable_only: + if not os.path.dirname(elf) in shell_path: + continue + do_marking = False + while True: + if allyes: + ans = 'y' + else: + ans = get_input('\tSet flags for %s (y/n): ' % elf) + if ans == 'y': + do_marking = True + break + elif ans == 'n': + do_marking = False + break + else: + print('\t\tPlease enter y or n') + if do_marking: + try: + migrate_flags(elf, library_str_flags, library_bin_flags) + except pax.PaxError: + print('\n\tCould not set pax flags on %s, file is probably busy' % elf) + print('\tShut down all processes that use it and try again') + (elf_str_flags, elf_bin_flags) = pax.getflags(elf) + print('\n\t\t%s ( %s )\n' % (elf, elf_str_flags )) 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 binaries') - 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('') + 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('') def main(): - # Are we root? - uid = os.getuid() - if uid != 0: - print('This program must be run as root') - sys.exit(1) - - 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' - run_usage() - sys.exit(1) - - if len(opts) == 0: - run_usage() - sys.exit(1) - - do_usage = False - do_forward = False - do_reverse = False - - elf = None - soname = None - library = None - - verbose = False - executable_only = False - mark = False - allyes = False - - opt_count = 0 - - for o, a in opts: - if o == '-h': - do_usage = True - opt_count += 1 - elif o == '-f': - do_forward = True - opt_count += 1 - elif o == '-r': - do_reverse = True - opt_count += 1 - elif o == '-b': - elf = a - opt_count += 1 - elif o == '-s': - soname = a - opt_count += 1 - elif o == '-l': - library = a - opt_count += 1 - elif o == '-v': - verbose = True - elif o == '-e': - executable_only = True - elif o == '-m': - mark = True - elif o == '-y': - allyes = True - else: - print('Option included in getopt but not handled here!') - print('Please file a bug') - sys.exit(1) - - # Only allow one of -h, -f -r -b -s - if opt_count > 1 or do_usage: - run_usage() - elif do_forward: - run_forward(verbose) - elif do_reverse: - run_reverse(verbose, executable_only) - elif elf != None: - run_elf(elf, verbose, mark, allyes) - elif soname != None: - run_soname(soname, verbose, True, mark, allyes, executable_only) - elif library != None: - library = os.path.realpath(library) - run_soname(library, verbose, False, mark, allyes, executable_only) + # Are we root? + uid = os.getuid() + if uid != 0: + print('This program must be run as root') + sys.exit(1) + + 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' + run_usage() + sys.exit(1) + + if len(opts) == 0: + run_usage() + sys.exit(1) + + do_usage = False + do_forward = False + do_reverse = False + + elf = None + soname = None + library = None + + verbose = False + executable_only = False + mark = False + allyes = False + + opt_count = 0 + + for o, a in opts: + if o == '-h': + do_usage = True + opt_count += 1 + elif o == '-f': + do_forward = True + opt_count += 1 + elif o == '-r': + do_reverse = True + opt_count += 1 + elif o == '-b': + elf = a + opt_count += 1 + elif o == '-s': + soname = a + opt_count += 1 + elif o == '-l': + library = a + opt_count += 1 + elif o == '-v': + verbose = True + elif o == '-e': + executable_only = True + elif o == '-m': + mark = True + elif o == '-y': + allyes = True + else: + print('Option included in getopt but not handled here!') + print('Please file a bug') + sys.exit(1) + + # Only allow one of -h, -f -r -b -s + if opt_count > 1 or do_usage: + run_usage() + elif do_forward: + run_forward(verbose) + elif do_reverse: + run_reverse(verbose, executable_only) + elif elf != None: + run_elf(elf, verbose, mark, allyes) + elif soname != None: + run_soname(soname, verbose, True, mark, allyes, executable_only) + elif library != None: + library = os.path.realpath(library) + run_soname(library, verbose, False, mark, allyes, executable_only) if __name__ == '__main__': - main() + main() |