aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-12-26 20:58:33 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-12-28 20:11:29 -0500
commit29630e205dcfda04d87679a2156948bd86c1a6a9 (patch)
tree3a627cc0bf5c70952fd9d8d4cf99ec5faca12117
parentmisc/link_map.py: place class in its own module (diff)
downloadelfix-29630e205dcfda04d87679a2156948bd86c1a6a9.tar.gz
elfix-29630e205dcfda04d87679a2156948bd86c1a6a9.tar.bz2
elfix-29630e205dcfda04d87679a2156948bd86c1a6a9.zip
misc/alt-revdep-pax: cleanup wrt object with no pax flags
-rw-r--r--.gitignore3
-rwxr-xr-xmisc/alt-revdep-pax1001
2 files changed, 433 insertions, 571 deletions
diff --git a/.gitignore b/.gitignore
index b0085b6..d4a46df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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()