diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/migrate-pax | 281 |
1 files changed, 143 insertions, 138 deletions
diff --git a/scripts/migrate-pax b/scripts/migrate-pax index 09a41e2..1460c71 100755 --- a/scripts/migrate-pax +++ b/scripts/migrate-pax @@ -1,160 +1,165 @@ #!/usr/bin/env python - # -# Note: This alternative way of doing revdep-pax only -# works on Gentoo systems where NEEDED.ELF.2 all the -# information we need generated by scanelf during emerge. +# migrate-pax: this file is part of the elfix package +# Copyright (C) 2012 Anthony G. Basile # -# See /usr/lib/portage/bin/misc-functions.sh ~line 520 -# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +# 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 import os import re import getopt import sys import pax +import portage + +def get_objects(): -def get_object_needed(): + vardb = portage.db[portage.root]["vartree"].dbapi - var_db_pkg = '/var/db/pkg' + objects = [] - object_needed = {} - for cat in os.listdir(var_db_pkg): - catdir = '%s/%s' % (var_db_pkg, cat) - for pkg in os.listdir(catdir): - pkgdir = '%s/%s' % (catdir, pkg) - need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2') - try: - g = open(need, 'r') - needs = g.readlines() - for line in needs: - line = line.strip() - link = re.split(';', line) - elf = link[1] - sonames = re.split(',', link[4]) - object_needed[elf] = sonames - except IOError: - continue #File probably doesn't exist, which is okay + 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 + continue + for line in re.split('\n', needed): + link = re.split(';', line) + objects.append(link[1]) # link[1] is the ELF object - return object_needed + return objects def run_usage(): - print('Package Name : elfix') - print('Bug Reports : http://bugs.gentoo.org/') - print('Program Name : migrate') - print('Description : Migrate PT_PAX to XATTR_PAX Flags on all system ELF objects') - print('') - print('Usage : migrate -v print out all system ELF objects') - print(' : migrate -m [-v] migrate flags on all system ELF objects') - print(' : migrate -d [-v] delete XATTR_PAX on all system ELF objects') - print(' : migrate [-h] print out this help') - print(' : -v be verbose when migrating') - print('') + print('Package Name : elfix') + print('Bug Reports : http://bugs.gentoo.org/') + print('Program Name : migrate') + print('Description : Migrate PT_PAX to XATTR_PAX Flags on all system ELF objects') + print('') + print('Usage : migrate -v print out all system ELF objects') + print(' : migrate -m [-v] migrate flags on all system ELF objects') + print(' : migrate -d [-v] delete XATTR_PAX on all system ELF objects') + print(' : migrate [-h] print out this help') + print(' : -v be verbose when migrating') + 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:], 'vmdh') - except getopt.GetoptError as err: - print(str(err)) # will print something like 'option -a not recognized' - run_usage() - sys.exit(1) - - verbose = False - do_migration = False - do_deleteall = False - do_usage = False - - opt_count = 0 - - for o, a in opts: - if o == '-v': - verbose = True - opt_count += 1 - elif o == '-m': - do_migration = True - opt_count += 1 - elif o == '-d': - do_deleteall = True - opt_count += 1 - elif o == '-h': - do_usage = True - opt_count += 1 - else: - print('Option included in getopt but not handled here!') - print('Please file a bug') - sys.exit(1) - - if do_usage: - run_usage() - sys.exit(0) - - if opt_count == 0 or opt_count > 2 or ( do_migration and do_deleteall): - run_usage() - sys.exit(1) - - # Do we have XATTR_PAX support? - if do_migration or do_deleteall: - 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') - sys.exit(1) - - object_needed = get_object_needed() - - fail = [] - none = [] - - for elf in object_needed: - try: - flags = pax.getflags(elf)[0] - if flags: - if verbose: - print("%s %s" % (flags, elf)) - else: - none.append(elf) - if verbose: - print("NONE: %s" % elf) - - if do_migration: - flags = re.sub('-','',flags) - pax.setstrflags(elf, flags) - - if do_deleteall: - pax.deletextpax(elf) - - # We should never get here, because you can - # always getflags() via pax.so since you can - # read PT_PAX even from a busy text file, and - # you can always set the pax flags with pax.so - # even on a busy text file because it will skip - # setting PT_PAX and only set the XATTR_PAX - except pax.PaxError: - if uid == 0: - fail.append(elf) - if verbose: - print("FAIL: %s" % elf) - - if verbose: - if fail: - print('\n') - print("ELF executables for which the migration failed:") - for elf in fail: - print("\t%s" % elf) - if none: - print('\n') - print("ELF executables lacking PT_PAX:") - for elf in none: - print("\t%s" % elf) + # 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:], 'vmdh') + except getopt.GetoptError as err: + print(str(err)) # will print something like 'option -a not recognized' + run_usage() + sys.exit(1) + + verbose = False + do_migration = False + do_deleteall = False + do_usage = False + + opt_count = 0 + + for o, a in opts: + if o == '-v': + verbose = True + opt_count += 1 + elif o == '-m': + do_migration = True + opt_count += 1 + elif o == '-d': + do_deleteall = True + opt_count += 1 + elif o == '-h': + do_usage = True + opt_count += 1 + else: + print('Option included in getopt but not handled here!') + print('Please file a bug') + sys.exit(1) + + if do_usage: + run_usage() + sys.exit(0) + + if opt_count == 0 or opt_count > 2 or ( do_migration and do_deleteall): + run_usage() + sys.exit(1) + + # Do we have XATTR_PAX support? + if do_migration or do_deleteall: + 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') + sys.exit(1) + + objects = get_objects() + + fail = [] + none = [] + + for elf in objects: + try: + flags = pax.getflags(elf)[0] + if flags: + if verbose: + print("%s %s" % (flags, elf)) + else: + none.append(elf) + if verbose: + print("NONE: %s" % elf) + + if do_migration: + flags = re.sub('-','',flags) + pax.setstrflags(elf, flags) + + if do_deleteall: + pax.deletextpax(elf) + + # We should never get here, because you can + # always getflags() via pax.so since you can + # read PT_PAX even from a busy text file, and + # you can always set the pax flags with pax.so + # even on a busy text file because it will skip + # setting PT_PAX and only set the XATTR_PAX + except pax.PaxError: + if uid == 0: + fail.append(elf) + if verbose: + print("FAIL: %s" % elf) + + if verbose: + if fail: + print('\n') + print("ELF executables for which the migration failed:") + for elf in fail: + print("\t%s" % elf) + if none: + print('\n') + print("ELF executables lacking PT_PAX:") + for elf in none: + print("\t%s" % elf) if __name__ == '__main__': - main() + main() |