aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/migrate-pax281
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()